This is an automated email from the ASF dual-hosted git repository.
marat pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-karavan.git
The following commit(s) were added to refs/heads/main by this push:
new 90b8ffb Saas feature31 (#418)
90b8ffb is described below
commit 90b8ffbec4b5d850049d0d3ca4264f563f067e7c
Author: Marat Gubaidullin <[email protected]>
AuthorDate: Mon Jul 18 09:39:10 2022 -0400
Saas feature31 (#418)
* Fix environment issues
* Improve Pipeline PVC management
* ImageTag api
* Fix
---
.../camel/karavan/api/ConfigurationResource.java | 4 +-
.../camel/karavan/api/KubernetesResource.java | 12 +++
.../apache/camel/karavan/api/StatusResource.java | 32 +++++++-
.../camel/karavan/service/GeneratorService.java | 3 -
.../camel/karavan/service/InfinispanService.java | 1 +
.../camel/karavan/service/KubernetesService.java | 23 ++++++
.../camel/karavan/service/StatusService.java | 3 -
karavan-app/src/main/webapp/src/api/KaravanApi.tsx | 2 +-
.../main/webapp/src/projects/ProjectDashboard.tsx | 90 +++++++++-------------
.../src/main/webapp/src/projects/ProjectHeader.tsx | 54 -------------
.../src/main/webapp/src/projects/ProjectInfo.tsx | 14 +++-
.../src/main/webapp/src/projects/ProjectPage.tsx | 30 +++++---
.../src/main/webapp/src/projects/ProjectsPage.tsx | 2 +-
karavan-builder/README.md | 6 ++
karavan-builder/openshift/karavan-acl.yaml | 31 +++-----
.../openshift/karavan-act-environments.yaml | 13 ++++
.../openshift/karavan-quarkus-pipeline.yaml | 8 ++
.../openshift/karavan-quarkus-task.yaml | 20 ++---
karavan-builder/openshift/kustomization.yaml | 1 -
19 files changed, 182 insertions(+), 167 deletions(-)
diff --git
a/karavan-app/src/main/java/org/apache/camel/karavan/api/ConfigurationResource.java
b/karavan-app/src/main/java/org/apache/camel/karavan/api/ConfigurationResource.java
index b2f23ef..04f6f75 100644
---
a/karavan-app/src/main/java/org/apache/camel/karavan/api/ConfigurationResource.java
+++
b/karavan-app/src/main/java/org/apache/camel/karavan/api/ConfigurationResource.java
@@ -44,7 +44,9 @@ public class ConfigurationResource {
return Response.ok(
Map.of(
"version", version,
- "environments",
configuration.environments().stream().map(e ->
e.name()).collect(Collectors.toList()),
+ "environments", configuration.environments().stream()
+ .filter(e -> e.active())
+ .map(e ->
e.name()).collect(Collectors.toList()),
"runtime", configuration.runtime()
)
).build();
diff --git
a/karavan-app/src/main/java/org/apache/camel/karavan/api/KubernetesResource.java
b/karavan-app/src/main/java/org/apache/camel/karavan/api/KubernetesResource.java
index b97c1e6..1a0476f 100644
---
a/karavan-app/src/main/java/org/apache/camel/karavan/api/KubernetesResource.java
+++
b/karavan-app/src/main/java/org/apache/camel/karavan/api/KubernetesResource.java
@@ -33,6 +33,7 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
+import java.util.List;
import java.util.Optional;
@Path("/kubernetes")
@@ -140,6 +141,17 @@ public class KubernetesResource {
return Response.noContent().build();
}
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/imagetag/{environment}/{projectId}")
+ public Response getProjectImageTags(@HeaderParam("username") String
username, @PathParam("environment") String environment, @PathParam("projectId")
String projectId) throws Exception {
+ Optional<KaravanConfiguration.Environment> env =
configuration.environments().stream().filter(e ->
e.name().equals(environment)).findFirst();
+ if (env.isPresent()) {
+ return
Response.ok(kubernetesService.getProjectImageTags(projectId,
env.get().namespace())).build();
+ }
+ return Response.noContent().build();
+ }
+
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/configmap/{environment}")
diff --git
a/karavan-app/src/main/java/org/apache/camel/karavan/api/StatusResource.java
b/karavan-app/src/main/java/org/apache/camel/karavan/api/StatusResource.java
index 5bc23b4..054730a 100644
--- a/karavan-app/src/main/java/org/apache/camel/karavan/api/StatusResource.java
+++ b/karavan-app/src/main/java/org/apache/camel/karavan/api/StatusResource.java
@@ -31,6 +31,8 @@ import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
+import java.util.HashMap;
+import java.util.Map;
import java.util.stream.Collectors;
@Path("/status")
@@ -49,8 +51,8 @@ public class StatusResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
- @Path("/{projectId}")
- public ProjectStatus getStatus(@HeaderParam("username") String username,
@PathParam("projectId") String projectId) throws Exception {
+ @Path("/project/{projectId}")
+ public ProjectStatus getStatus(@HeaderParam("username") String username,
@PathParam("projectId") String projectId) {
bus.publish(StatusService.CMD_COLLECT_STATUSES, projectId);
ProjectStatus status = infinispanService.getProjectStatus(projectId);
if (status != null){
@@ -63,4 +65,30 @@ public class StatusResource {
Long.valueOf(0));
}
}
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/projects")
+ public Map<String, Map> getSimpleStatus(@HeaderParam("username") String
username) throws Exception {
+ Map<String, Map> result = new HashMap<>();
+ infinispanService.getProjects().forEach(project -> {
+ ProjectStatus ps = getStatus(username, project.getProjectId());
+ Map<String, String> statuses = new HashMap<>();
+ ps.getStatuses().forEach(pes -> {
+ if (pes.getLastPipelineRunResult() == null ||
pes.getDeploymentStatus() == null || pes.getContextStatus() == null){
+ statuses.put(pes.getEnvironment(), "N/A");
+ } else {
+ boolean pipelineOK =
pes.getLastPipelineRunResult().equals("Succeeded");
+ System.out.println(pes.getLastPipelineRunResult());
+ boolean deploymentOK =
pes.getDeploymentStatus().getReadyReplicas() ==
pes.getDeploymentStatus().getReplicas() &&
pes.getDeploymentStatus().getUnavailableReplicas() == 0;
+ boolean camelOK =
pes.getContextStatus().equals(ProjectEnvStatus.Status.UP) &&
pes.getConsumerStatus().equals(ProjectEnvStatus.Status.UP) &&
pes.getRoutesStatus().equals(ProjectEnvStatus.Status.UP);
+ String status = (pipelineOK && deploymentOK && camelOK) ?
"UP" : "DOWN";
+ statuses.put(pes.getEnvironment(), status);
+ }
+ });
+ result.put(project.getProjectId(), statuses);
+ });
+
+ return result;
+ }
}
\ No newline at end of file
diff --git
a/karavan-app/src/main/java/org/apache/camel/karavan/service/GeneratorService.java
b/karavan-app/src/main/java/org/apache/camel/karavan/service/GeneratorService.java
index 220cb6a..ffcae12 100644
---
a/karavan-app/src/main/java/org/apache/camel/karavan/service/GeneratorService.java
+++
b/karavan-app/src/main/java/org/apache/camel/karavan/service/GeneratorService.java
@@ -69,9 +69,6 @@ public class GeneratorService {
.append("mvn:io.quarkus:quarkus-openshift").append(System.lineSeparator());
s.append("camel.health.enabled=true").append(System.lineSeparator());
-
s.append("camel.health.routes-enabled=true").append(System.lineSeparator());
-
s.append("camel.health.consumers-enabled=true").append(System.lineSeparator());
-
s.append("camel.health.registry-enabled=true").append(System.lineSeparator());
s.append("camel.health.exposure-level=full").append(System.lineSeparator());
s.append("quarkus.container-image.group=").append(imageGroup).append(System.lineSeparator());
diff --git
a/karavan-app/src/main/java/org/apache/camel/karavan/service/InfinispanService.java
b/karavan-app/src/main/java/org/apache/camel/karavan/service/InfinispanService.java
index 1cdcbad..ed42868 100644
---
a/karavan-app/src/main/java/org/apache/camel/karavan/service/InfinispanService.java
+++
b/karavan-app/src/main/java/org/apache/camel/karavan/service/InfinispanService.java
@@ -34,6 +34,7 @@ import
org.infinispan.commons.configuration.XMLStringConfiguration;
import org.infinispan.configuration.cache.CacheMode;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.configuration.cache.SingleFileStoreConfigurationBuilder;
+import org.infinispan.configuration.cache.StorageType;
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.query.dsl.QueryFactory;
diff --git
a/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java
b/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java
index a75b4c8..4e76a63 100644
---
a/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java
+++
b/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java
@@ -23,6 +23,7 @@ import io.fabric8.kubernetes.api.model.Secret;
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.openshift.api.model.DeploymentConfig;
+import io.fabric8.openshift.api.model.ImageStream;
import io.fabric8.openshift.client.OpenShiftClient;
import io.fabric8.tekton.client.DefaultTektonClient;
import io.fabric8.tekton.pipeline.v1beta1.ParamBuilder;
@@ -32,6 +33,7 @@ import io.fabric8.tekton.pipeline.v1beta1.PipelineRun;
import io.fabric8.tekton.pipeline.v1beta1.PipelineRunBuilder;
import io.fabric8.tekton.pipeline.v1beta1.PipelineRunSpec;
import io.fabric8.tekton.pipeline.v1beta1.PipelineRunSpecBuilder;
+import io.fabric8.tekton.pipeline.v1beta1.WorkspaceBindingBuilder;
import org.apache.camel.karavan.model.DeploymentStatus;
import org.apache.camel.karavan.model.PipelineRunLog;
import org.apache.camel.karavan.model.PodStatus;
@@ -42,6 +44,7 @@ import org.jboss.logging.Logger;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import java.util.ArrayList;
+import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -90,6 +93,9 @@ public class KubernetesService {
.withPipelineRef(ref)
.withServiceAccountName("pipeline")
.withParams(new
ParamBuilder().withName("PROJECT_NAME").withNewValue(project.getProjectId()).build())
+ .withWorkspaces(
+ new
WorkspaceBindingBuilder().withName("m2-cache").withNewPersistentVolumeClaim("karavan-m2-cache",
false).build(),
+ new
WorkspaceBindingBuilder().withName("jbang-cache").withNewPersistentVolumeClaim("karavan-jbang-cache",
false).build())
.build();
PipelineRunBuilder pipelineRunBuilder = new PipelineRunBuilder()
@@ -241,6 +247,23 @@ public class KubernetesService {
return result;
}
+ public List<String> getProjectImageTags (String projectId, String
namespace){
+ List<String> result = new ArrayList<>();
+ try {
+ if (kubernetesClient().isAdaptable(OpenShiftClient.class)) {
+ ImageStream is =
openshiftClient().imageStreams().inNamespace(namespace).withName(projectId).get();
+ if (is != null) {
+ result.addAll(is.getSpec().getTags().stream().map(t ->
t.getName()).sorted(Comparator.reverseOrder()).collect(Collectors.toList()));
+ }
+ } else {
+ // TODO: Implement for Kubernetes/Minikube
+ }
+ } catch (Exception ex) {
+ LOGGER.error(ex.getMessage());
+ }
+ return result;
+ }
+
public Secret getKaravanSecret() {
return
kubernetesClient().secrets().inNamespace(currentNamespace).withName("karavan").get();
}
diff --git
a/karavan-app/src/main/java/org/apache/camel/karavan/service/StatusService.java
b/karavan-app/src/main/java/org/apache/camel/karavan/service/StatusService.java
index cf8ca70..a07889f 100644
---
a/karavan-app/src/main/java/org/apache/camel/karavan/service/StatusService.java
+++
b/karavan-app/src/main/java/org/apache/camel/karavan/service/StatusService.java
@@ -79,7 +79,6 @@ public class StatusService {
}
private void getStatuses(String projectId) throws Exception {
- LOGGER.info("Start to collect statuses for the project " + projectId);
ProjectStatus old = infinispanService.getProjectStatus(projectId);
ProjectStatus status = new ProjectStatus();
status.setProjectId(projectId);
@@ -109,8 +108,6 @@ public class StatusService {
statuses.add(pes);
});
status.setStatuses(statuses);
-
- LOGGER.info("Storing status in cache for " + projectId);
infinispanService.saveProjectStatus(status);
}
diff --git a/karavan-app/src/main/webapp/src/api/KaravanApi.tsx
b/karavan-app/src/main/webapp/src/api/KaravanApi.tsx
index a1146bd..7a2e172 100644
--- a/karavan-app/src/main/webapp/src/api/KaravanApi.tsx
+++ b/karavan-app/src/main/webapp/src/api/KaravanApi.tsx
@@ -28,7 +28,7 @@ export const KaravanApi = {
},
getProjectStatus: async (projectId: string, after: (status: ProjectStatus)
=> void) => {
- axios.get('/status/' + projectId,
+ axios.get('/status/project/' + projectId,
{headers: {'Accept': 'application/json', 'username': 'cameleer'}})
.then(res => {
if (res.status === 200) {
diff --git a/karavan-app/src/main/webapp/src/projects/ProjectDashboard.tsx
b/karavan-app/src/main/webapp/src/projects/ProjectDashboard.tsx
index 40e7b6c..96b9ea5 100644
--- a/karavan-app/src/main/webapp/src/projects/ProjectDashboard.tsx
+++ b/karavan-app/src/main/webapp/src/projects/ProjectDashboard.tsx
@@ -7,8 +7,8 @@ import {
} from '@patternfly/react-core';
import '../designer/karavan.css';
import {KaravanApi} from "../api/KaravanApi";
-import {Project, ProjectFileTypes, ProjectStatus} from
"../models/ProjectModels";
-import {ChartDonut} from "@patternfly/react-charts";
+import {Project, ProjectEnvStatus, ProjectFileTypes, ProjectStatus} from
"../models/ProjectModels";
+import {ChartDonut, ChartDonutThreshold, ChartDonutUtilization} from
"@patternfly/react-charts";
interface Props {
project: Project,
@@ -19,7 +19,6 @@ interface Props {
interface State {
project?: Project,
status?: ProjectStatus,
-
key?: string,
}
@@ -71,32 +70,6 @@ export class ProjectDashboard extends React.Component<Props,
State> {
}
}
- getCurrentStatus() {
- return (<Text>OK</Text>)
- }
-
- // getPipelineState() {
- // const {project, status} = this.state;
- // const isRunning = status?.pipeline === 'Running';
- // const isFailed = status?.pipeline === 'Failed';
- // const isSucceeded = status?.pipeline === 'Succeeded';
- // let classname = "pipeline"
- // if (isRunning) classname = classname + " pipeline-running";
- // if (isFailed) classname = classname + " pipeline-running";
- // if (isSucceeded) classname = classname + " pipeline-succeeded";
- // return (
- // <Flex spaceItems={{default: 'spaceItemsNone'}}
className={classname} direction={{default: "row"}}
- // alignItems={{default: "alignItemsCenter"}}>
- // <FlexItem style={{height: "18px"}}>
- // {isRunning && <Spinner isSVG diameter="16px"/>}
- // </FlexItem>
- // <FlexItem style={{height: "18px"}}>
- // {project?.lastPipelineRun ? project?.lastPipelineRun :
"-"}
- // </FlexItem>
- // </Flex>
- // )
- // }
-
isUp(env: string): boolean {
if (this.state.status) {
return this.state.status.statuses.find(s => s.environment ===
env)?.status === 'UP';
@@ -105,30 +78,39 @@ export class ProjectDashboard extends
React.Component<Props, State> {
}
}
- getEnvironmentData() {
- const used = true;
- const replicas = 3;
- const data = Array.from({length: replicas}, (v, k) => {
- return { x: k, y: 100/replicas }
- });
- const readyReplicas = 2;
- const colorScale = Array.from({length: replicas}, (v, k) => {
- console.log(" " + k)
- if (k < readyReplicas) return "rgb(56, 129, 47)"
- else return "#8bc1f7"
- })
- return (
- <div style={{ height: '130px', width: '130px' }}>
- <ChartDonut
- constrainToVisibleArea={true}
- data={data}
- colorScale={colorScale}
- labels={({ datum }) => datum.x ? datum.x : null}
- title="Pods"
- >
- </ChartDonut>
- </div>
- );
+ getEnvironmentData(env: string) {
+ const pes = this.state.status?.statuses.find(s => s.environment ==
env);
+ if (pes){
+ const replicas = pes.deploymentStatus.replicas;
+ const data = Array.from({length: replicas}, (v, k) => {
+ return { x: k, y: 100/replicas }
+ });
+ const unavailableReplicas =
pes.deploymentStatus.unavailableReplicas;
+ const dataU = Array.from({length: unavailableReplicas}, (v, k) => {
+ return { x: k, y: 100/unavailableReplicas }
+ });
+ const readyReplicas = pes.deploymentStatus.readyReplicas;
+ const colorScale = Array.from({length: replicas}, (v, k) => {
+ if (k < readyReplicas) return "rgb(56, 129, 47)"
+ else return "#8bc1f7"
+ })
+ return (
+ <div style={{ height: '185px', width: '185px' }}>
+ <ChartDonutThreshold
+ constrainToVisibleArea
+ data={data}
+ colorScale={colorScale}
+ height={185}
+ width={185}
+ >
+ <ChartDonutThreshold
+ data={dataU}
+ title="Pods"
+ />
+ </ChartDonutThreshold>
+ </div>
+ );
+ }
}
render() {
@@ -145,7 +127,7 @@ export class ProjectDashboard extends
React.Component<Props, State> {
<Badge className={this.isUp(e) ?
"badge-env-up" : ""} isRead>{e}</Badge>
</FlexItem>
<FlexItem>
- {this.getEnvironmentData()}
+ {this.getEnvironmentData(e)}
</FlexItem>
</Flex>
</CardBody>
diff --git a/karavan-app/src/main/webapp/src/projects/ProjectHeader.tsx
b/karavan-app/src/main/webapp/src/projects/ProjectHeader.tsx
deleted file mode 100644
index 29880f9..0000000
--- a/karavan-app/src/main/webapp/src/projects/ProjectHeader.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-import React from 'react';
-import {
- Flex,
- FlexItem,
- Tabs,
- Tab,
- PageSection,
-} from '@patternfly/react-core';
-import '../designer/karavan.css';
-import {Project, ProjectStatus} from "../models/ProjectModels";
-import {ProjectDashboard} from "./ProjectDashboard";
-import {ProjectInfo} from "./ProjectInfo";
-
-interface Props {
- project: Project,
- config: any,
- environments: string [],
- showLog: (type: 'container' | 'pipeline', name: string, environment:
string) => void
- deleteEntity: (type: 'pod' | 'deployment', name: string, environment:
string) => void
-}
-
-interface State {
- project?: Project,
- status?: ProjectStatus,
- tab: string | number;
-}
-
-export class ProjectHeader extends React.Component<Props, State> {
-
- public state: State = {
- project: this.props.project,
- tab: "details"
- };
-
- render() {
- const {tab} = this.state;
- return (
- <Flex direction={{default: "column"}} spaceItems={{default:
"spaceItemsNone"}}>
- <FlexItem>
- <Tabs activeKey={tab} onSelect={(event, tabIndex) =>
this.setState({tab: tabIndex})}>
- <Tab eventKey="details" title="Details"/>
- <Tab eventKey="dashboard" title="Dashboard"/>
- </Tabs>
- </FlexItem>
- <FlexItem>
- <PageSection padding={{default: "padding"}}>
- {tab === 'details' && <ProjectInfo
project={this.props.project} config={this.props.config}
deleteEntity={this.props.deleteEntity} showLog={this.props.showLog}/>}
- {tab === 'dashboard' && <ProjectDashboard
environments={this.props.environments} project={this.props.project}
config={this.props.config}/>}
- </PageSection>
- </FlexItem>
- </Flex>
- )
- }
-}
diff --git a/karavan-app/src/main/webapp/src/projects/ProjectInfo.tsx
b/karavan-app/src/main/webapp/src/projects/ProjectInfo.tsx
index cbc4820..ce726a5 100644
--- a/karavan-app/src/main/webapp/src/projects/ProjectInfo.tsx
+++ b/karavan-app/src/main/webapp/src/projects/ProjectInfo.tsx
@@ -2,7 +2,6 @@ import React from 'react';
import {
Badge,
Button,
- Text,
DescriptionList,
DescriptionListTerm,
DescriptionListGroup,
@@ -141,10 +140,17 @@ export class ProjectInfo extends React.Component<Props,
State> {
</Tooltip>)
}
- buildButton = () => {
+ buildButton = (env: string) => {
const isDeploying = this.state.isBuilding;
+ const isPushing = this.state.isPushing;
+ const status = this.state.status?.statuses.find(s => s.environment ===
env)
+ const pipelineResult = status?.lastPipelineRunResult;
+ const isRunning = pipelineResult === 'Running';
return (<Tooltip content="Commit, push, build and deploy"
position={"left"}>
- <Button isLoading={isDeploying ? true : undefined} isSmall
variant="secondary"
+ <Button isLoading={isDeploying ? true : undefined}
+ isDisabled={isDeploying || isRunning || isPushing}
+ isSmall
+ variant="secondary"
className="project-button"
icon={!isDeploying ? <BuildIcon/> : <div></div>}
onClick={e => {
@@ -347,7 +353,7 @@ export class ProjectInfo extends React.Component<Props,
State> {
</LabelGroup>
</Tooltip>
</FlexItem>
- <FlexItem>{env === "dev" && this.buildButton()}</FlexItem>
+ <FlexItem>{env === "dev" && this.buildButton(env)}</FlexItem>
</Flex>
)
}
diff --git a/karavan-app/src/main/webapp/src/projects/ProjectPage.tsx
b/karavan-app/src/main/webapp/src/projects/ProjectPage.tsx
index 631434c..a96ca7f 100644
--- a/karavan-app/src/main/webapp/src/projects/ProjectPage.tsx
+++ b/karavan-app/src/main/webapp/src/projects/ProjectPage.tsx
@@ -21,7 +21,7 @@ import {
ToggleGroup,
ToggleGroupItem,
CodeBlockCode,
- CodeBlock, Skeleton, Switch, Checkbox
+ CodeBlock, Skeleton, Switch, Checkbox, Tabs, Tab
} from '@patternfly/react-core';
import '../designer/karavan.css';
import {MainToolbar} from "../MainToolbar";
@@ -39,11 +39,12 @@ import SearchIcon from
'@patternfly/react-icons/dist/esm/icons/search-icon';
import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
import {CreateFileModal} from "./CreateFileModal";
import {PropertiesEditor} from "./PropertiesEditor";
-import {ProjectHeader} from "./ProjectHeader";
import {ProjectModel, ProjectProperty} from
"karavan-core/lib/model/ProjectModel";
import {ProjectModelApi} from "karavan-core/lib/api/ProjectModelApi";
import {KubernetesAPI} from "../designer/utils/KubernetesAPI";
import {UploadModal} from "./UploadModal";
+import {ProjectInfo} from "./ProjectInfo";
+import {ProjectDashboard} from "./ProjectDashboard";
interface Props {
project: Project,
@@ -64,6 +65,7 @@ interface State {
key: string
environments: string[],
environment: string,
+ tab: string | number;
}
export class ProjectPage extends React.Component<Props, State> {
@@ -77,6 +79,7 @@ export class ProjectPage extends React.Component<Props,
State> {
mode: "design",
editAdvancedProperties: false,
key: '',
+ tab: "details",
environments: this.props.config.environments &&
Array.isArray(this.props.config.environments)
? Array.from(this.props.config.environments) : [],
environment: this.props.config.environments &&
Array.isArray(this.props.config.environments)
@@ -421,7 +424,7 @@ export class ProjectPage extends React.Component<Props,
State> {
}
render() {
- const {file, mode} = this.state;
+ const {file, mode, tab} = this.state;
const isYaml = file !== undefined && file.name.endsWith("yaml");
const isProperties = file !== undefined &&
file.name.endsWith("properties");
const isLog = file !== undefined && file.name.endsWith("log");
@@ -436,12 +439,21 @@ export class ProjectPage extends React.Component<Props,
State> {
{file === undefined &&
<PageSection isFilled className="kamelets-page
project-page-section"
padding={{default: file !== undefined ?
'noPadding' : 'noPadding'}}>
- {<ProjectHeader project={this.props.project}
- config={this.props.config}
- environments={this.state.environments}
- showLog={this.showPipelineLog}
- deleteEntity={this.deleteEntity}/>}
- {this.getProjectFiles()}
+ <Flex direction={{default: "column"}}
spaceItems={{default: "spaceItemsNone"}}>
+ <FlexItem>
+ <Tabs activeKey={tab} onSelect={(event,
tabIndex) => this.setState({tab: tabIndex})}>
+ <Tab eventKey="details" title="Details"/>
+ <Tab eventKey="dashboard"
title="Dashboard"/>
+ </Tabs>
+ </FlexItem>
+ <FlexItem>
+ <PageSection padding={{default: "padding"}}>
+ {tab === 'details' && <ProjectInfo
project={this.props.project} config={this.props.config}
deleteEntity={this.deleteEntity} showLog={this.showPipelineLog}/>}
+ {tab === 'dashboard' && <ProjectDashboard
environments={this.state.environments} project={this.props.project}
config={this.props.config}/>}
+ </PageSection>
+ </FlexItem>
+ </Flex>
+ {tab === 'details' && this.getProjectFiles()}
</PageSection>}
{showDesigner && this.getDesigner()}
{showEditor && this.getEditor()}
diff --git a/karavan-app/src/main/webapp/src/projects/ProjectsPage.tsx
b/karavan-app/src/main/webapp/src/projects/ProjectsPage.tsx
index 1e0d65a..3c32227 100644
--- a/karavan-app/src/main/webapp/src/projects/ProjectsPage.tsx
+++ b/karavan-app/src/main/webapp/src/projects/ProjectsPage.tsx
@@ -166,7 +166,7 @@ export class ProjectsPage extends React.Component<Props,
State> {
<Th key='name'>Name</Th>
<Th key='description'>Description</Th>
<Th key='commit'>Commit</Th>
- <Th key='deployment'>Deployment</Th>
+ <Th key='deployment'>Environment</Th>
<Th key='action'></Th>
</Tr>
</Thead>
diff --git a/karavan-builder/README.md b/karavan-builder/README.md
index b782152..638573a 100644
--- a/karavan-builder/README.md
+++ b/karavan-builder/README.md
@@ -2,3 +2,9 @@
```
docker build -t apache/camel-karavan-builder .
```
+
+### To deploy to test and prod from karavan namespace
+```
+oc policy add-role-to-user system:image-puller
system:serviceaccount:test:default --namespace=karavan
+oc policy add-role-to-user system:image-puller
system:serviceaccount:prod:default --namespace=karavan
+```
diff --git a/karavan-builder/openshift/karavan-acl.yaml
b/karavan-builder/openshift/karavan-acl.yaml
index 7670950..eb86382 100644
--- a/karavan-builder/openshift/karavan-acl.yaml
+++ b/karavan-builder/openshift/karavan-acl.yaml
@@ -13,28 +13,15 @@ kind: Role
metadata:
name: karavan-app
rules:
- - apiGroups:
- - ""
- resources:
- - secrets
- - configmaps
- verbs:
- - get
- - list
- - apiGroups:
- - ""
- - apps.openshift.io
- resources:
- - deploymentconfigs
- - replicationcontrollers
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
+ - apiGroups: [""]
+ resources: ["secrets", "configmaps"]
+ verbs: ["get", "list"]
+ - apiGroups: [""]
+ resources: ["persistentvolumes", "persistentvolumeclaims"]
+ verbs: ["*"]
+ - apiGroups: ["", "apps.openshift.io"]
+ resources: ["deploymentconfigs", "replicationcontrollers"]
+ verbs: ["*"]
---
# Role tekton run pipeline
kind: Role
diff --git a/karavan-builder/openshift/karavan-act-environments.yaml
b/karavan-builder/openshift/karavan-act-environments.yaml
new file mode 100644
index 0000000..737d51a
--- /dev/null
+++ b/karavan-builder/openshift/karavan-act-environments.yaml
@@ -0,0 +1,13 @@
+kind: RoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+ name: karavan-image-puller-test
+ namespace: karavan
+subjects:
+ - kind: ServiceAccount
+ name: default
+ namespace: test
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: 'system:image-puller'
\ No newline at end of file
diff --git a/karavan-builder/openshift/karavan-quarkus-pipeline.yaml
b/karavan-builder/openshift/karavan-quarkus-pipeline.yaml
index fa15bc7..20b2710 100644
--- a/karavan-builder/openshift/karavan-quarkus-pipeline.yaml
+++ b/karavan-builder/openshift/karavan-quarkus-pipeline.yaml
@@ -14,3 +14,11 @@ spec:
taskRef:
kind: Task
name: karavan-quarkus-builder
+ workspaces:
+ - name: m2-cache
+ workspace: m2-cache
+ - name: jbang-cache
+ workspace: jbang-cache
+ workspaces:
+ - name: m2-cache
+ - name: jbang-cache
\ No newline at end of file
diff --git a/karavan-builder/openshift/karavan-quarkus-task.yaml
b/karavan-builder/openshift/karavan-quarkus-task.yaml
index 5d39b42..1acfe14 100644
--- a/karavan-builder/openshift/karavan-quarkus-task.yaml
+++ b/karavan-builder/openshift/karavan-quarkus-task.yaml
@@ -12,6 +12,9 @@ spec:
#!/usr/bin/env bash
CHECKOUT_DIR="/scripts"
+ ls -la $(workspaces.m2-cache.path)
+ ls -la $(workspaces.jbang-cache.path)
+
if [[ $GIT_REPOSITORY == https* ]] ;
then
replacer=https://$GIT_PASSWORD@
@@ -45,11 +48,6 @@ spec:
-Dquarkus.container-image.group=${NAMESPACE} \
-Dquarkus.container-image.tag=${DATE}
image: 'ghcr.io/apache/camel-karavan-builder:0.0.16'
- volumeMounts:
- - mountPath: /root/.m2
- name: m2-cache
- - mountPath: /jbang/.jbang/cache
- name: jbang-cache
env:
- name: GIT_REPOSITORY
valueFrom:
@@ -73,10 +71,8 @@ spec:
#!/usr/bin/env bash
oc label dc/$(inputs.params.project) app.openshift.io/runtime=camel
--overwrite=true
oc rollout latest dc/$(inputs.params.project)
- volumes:
- - name: m2-cache
- persistentVolumeClaim:
- claimName: karavan-m2-cache
- - name: jbang-cache
- persistentVolumeClaim:
- claimName: karavan-jbang-cache
+ workspaces:
+ - mountPath: /root/.m2
+ name: m2-cache
+ - mountPath: /jbang/.jbang/cache
+ name: jbang-cache
\ No newline at end of file
diff --git a/karavan-builder/openshift/kustomization.yaml
b/karavan-builder/openshift/kustomization.yaml
index ddd4e52..b046577 100644
--- a/karavan-builder/openshift/kustomization.yaml
+++ b/karavan-builder/openshift/kustomization.yaml
@@ -2,7 +2,6 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
-- pipeline-operator.yaml
- karavan-namespace.yaml
- karavan-acl.yaml
- karavan-pvc.yaml