Skip to content

Commit

Permalink
implemented scale action (#615)
Browse files Browse the repository at this point in the history
Signed-off-by: Andre Dietisheim <[email protected]>
  • Loading branch information
adietish committed Aug 25, 2023
1 parent 4425254 commit 7919bf1
Show file tree
Hide file tree
Showing 18 changed files with 1,179 additions and 98 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*******************************************************************************
* Copyright (c) 2023 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package com.redhat.devtools.intellij.kubernetes.actions

import com.intellij.openapi.actionSystem.AnActionEvent
import com.redhat.devtools.intellij.common.actions.StructureTreeAction
import com.redhat.devtools.intellij.kubernetes.dialogs.ScaleReplicaDialog
import com.redhat.devtools.intellij.kubernetes.model.Notification
import com.redhat.devtools.intellij.kubernetes.model.util.toMessage
import io.fabric8.kubernetes.api.model.HasMetadata
import io.fabric8.kubernetes.api.model.Pod
import io.fabric8.kubernetes.api.model.ReplicationController
import io.fabric8.kubernetes.api.model.apps.Deployment
import io.fabric8.kubernetes.api.model.apps.ReplicaSet
import io.fabric8.kubernetes.api.model.apps.StatefulSet
import io.fabric8.openshift.api.model.DeploymentConfig
import java.awt.event.MouseEvent
import javax.swing.tree.TreePath

class ScaleReplicaAction: StructureTreeAction() {

override fun actionPerformed(event: AnActionEvent?, path: TreePath?, selected: Any?) {
// not called
}

override fun actionPerformed(event: AnActionEvent?, path: Array<out TreePath>?, selected: Array<out Any>?) {
val project = getEventProject(event) ?: return
val toScale = selected?.firstOrNull()?.getElement<HasMetadata>() ?: return
val model = getResourceModel() ?: return
try {
val replicator = model.getReplicas(toScale)
val replicas = replicator?.replicas
if (replicator == null
|| replicas == null) {
Notification().error(
"Error Scaling",
"Could not scale ${toScale.kind} '${toScale.metadata.name}: unsupported resource"
)
return
}
val resourceLabel = "${replicator.resource.kind} ${replicator.resource.metadata.name}"
ScaleReplicaDialog(
project,
resourceLabel,
replicas,
{ replicas: Int -> model.setReplicas(replicas, replicator)},
(event?.inputEvent as? MouseEvent)?.locationOnScreen
).show()
} catch (e: RuntimeException) {
Notification().error(
"Error Scaling",
"Could not scale ${toScale.kind} '${toScale.metadata.name}': ${toMessage(e)}"
)
}
}

override fun isVisible(selected: Array<out Any>?): Boolean {
return selected?.size == 1
&& isVisible(selected.firstOrNull())
}

override fun isVisible(selected: Any?): Boolean {
val element = selected?.getElement<HasMetadata>()
return element is Deployment
|| element is DeploymentConfig
|| element is ReplicationController
|| element is ReplicaSet
|| element is StatefulSet
|| element is Pod
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*******************************************************************************
* Copyright (c) 2023 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package com.redhat.devtools.intellij.kubernetes.dialogs

import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.DialogWrapper
import com.intellij.openapi.ui.ValidationInfo
import com.intellij.ui.JBIntSpinner
import com.intellij.ui.components.JBLabel
import java.awt.BorderLayout
import java.awt.Point
import javax.swing.JComponent
import javax.swing.JPanel
import javax.swing.SwingConstants

class ScaleReplicaDialog(
project: Project,
private val resourceLabel: String,
private val currentReplicas: Int,
private val onOk: (Int) -> Unit,
private val location: Point?
) : DialogWrapper(project, false) {

private val replicasSpinner = JBIntSpinner(
currentReplicas,
0,
Int.MAX_VALUE,
1
)

override fun createCenterPanel(): JComponent {
return JPanel(BorderLayout()).apply {
layout = BorderLayout(10, 10)
add(JBLabel(resourceLabel, SwingConstants.LEFT), BorderLayout.NORTH)
add(JBLabel("Replicas:", SwingConstants.LEFT), BorderLayout.LINE_START)
add(replicasSpinner, BorderLayout.CENTER)
}
}

override fun init() {
title = "Set Replicas"
setResizable(false)
setOKButtonText("Scale")
isModal = false
if (location != null) {
setLocation(location.x, location.y)
}
super.init()
}

override fun getPreferredFocusedComponent(): JComponent {
return replicasSpinner
}

override fun show() {
init()
super.show()
}

override fun doValidate(): ValidationInfo? {
return if (replicasSpinner.number == currentReplicas) {
ValidationInfo("Replicas unchanged", replicasSpinner)
} else {
null
}
}

override fun doOKAction() {
super.doOKAction()
onOk.invoke(replicasSpinner.number)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
******************************************************************************/
package com.redhat.devtools.intellij.kubernetes.model

import com.google.api.ResourceProto.resource
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.logger
import com.redhat.devtools.intellij.kubernetes.model.client.ClientAdapter
import com.redhat.devtools.intellij.kubernetes.model.context.IActiveContext
import com.redhat.devtools.intellij.kubernetes.model.context.IActiveContext.ResourcesIn
import com.redhat.devtools.intellij.kubernetes.model.context.IContext
import com.redhat.devtools.intellij.kubernetes.model.resource.ResourceKind
import com.redhat.devtools.intellij.kubernetes.model.resource.kubernetes.KubernetesReplicas.*
import io.fabric8.kubernetes.api.model.Container
import io.fabric8.kubernetes.api.model.HasMetadata
import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition
Expand All @@ -43,6 +45,8 @@ interface IResourceModel {
fun isCurrentNamespace(resource: HasMetadata): Boolean
fun <R: HasMetadata> resources(kind: ResourceKind<R>): Namespaceable<R>
fun resources(definition: CustomResourceDefinition): ListableCustomResources
fun setReplicas(replicas: Int, replicator: Replicator)
fun getReplicas(resource: HasMetadata): Replicator?
fun watch(kind: ResourceKind<out HasMetadata>)
fun watch(definition: CustomResourceDefinition)
fun stopWatch(kind: ResourceKind<out HasMetadata>)
Expand Down Expand Up @@ -127,6 +131,14 @@ open class ResourceModel : IResourceModel {
return allContexts.current?.getAllResources(definition) ?: emptyList()
}

override fun setReplicas(replicas: Int, replicator: Replicator) {
allContexts.current?.setReplicas(replicas, replicator)
}

override fun getReplicas(resource: HasMetadata): Replicator? {
return allContexts.current?.getReplicas(resource)
}

override fun watch(kind: ResourceKind<out HasMetadata>) {
allContexts.current?.watch(kind)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.redhat.devtools.intellij.kubernetes.model.client.ClientAdapter
import com.redhat.devtools.intellij.kubernetes.model.client.KubeClientAdapter
import com.redhat.devtools.intellij.kubernetes.model.client.OSClientAdapter
import com.redhat.devtools.intellij.kubernetes.model.resource.ResourceKind
import com.redhat.devtools.intellij.kubernetes.model.resource.kubernetes.KubernetesReplicas.Replicator
import io.fabric8.kubernetes.api.model.GenericKubernetesResource
import io.fabric8.kubernetes.api.model.HasMetadata
import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition
Expand Down Expand Up @@ -145,6 +146,25 @@ interface IActiveContext<N: HasMetadata, C: KubernetesClient>: IContext {
*/
fun replace(resource: HasMetadata): HasMetadata?

/**
* Sets the replicas for the given [Replicator]
*
* @param replicas the number of replicas to set
* @param replicator the resource to set the replicas to
*
* @see Replicator
*/
fun setReplicas(replicas: Int, replicator: Replicator)

/**
* Returns the replicas for the given resource.
* Returns `null` replicas are not defined or the given resource does not specify those.
*
* @param resource the resource to get the replicas from
* @return returns an instance of the resource that can be replicated or null if there's none
*/
fun getReplicas(resource: HasMetadata): Replicator?

/**
* Watches all resources of the given resource kind
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,15 @@ package com.redhat.devtools.intellij.kubernetes.model.context
import com.redhat.devtools.intellij.kubernetes.model.IResourceModelObservable
import com.redhat.devtools.intellij.kubernetes.model.client.ClientAdapter
import com.redhat.devtools.intellij.kubernetes.model.client.KubeClientAdapter
import com.redhat.devtools.intellij.kubernetes.model.context.IActiveContext.ResourcesIn
import com.redhat.devtools.intellij.kubernetes.model.dashboard.KubernetesDashboard
import com.redhat.devtools.intellij.kubernetes.model.resource.IResourceOperator
import com.redhat.devtools.intellij.kubernetes.model.resource.NonCachingSingleResourceOperator
import com.redhat.devtools.intellij.kubernetes.model.resource.OperatorFactory
import com.redhat.devtools.intellij.kubernetes.model.resource.ResourceKind
import com.redhat.devtools.intellij.kubernetes.model.resource.kubernetes.KubernetesReplicas
import com.redhat.devtools.intellij.kubernetes.model.resource.kubernetes.KubernetesReplicas.Replicator
import com.redhat.devtools.intellij.kubernetes.model.resource.kubernetes.KubernetesReplicas.ResourcesRetrieval
import com.redhat.devtools.intellij.kubernetes.model.resource.kubernetes.NamespacesOperator
import io.fabric8.kubernetes.api.model.HasMetadata
import io.fabric8.kubernetes.api.model.NamedContext
Expand All @@ -39,14 +44,33 @@ open class KubernetesContext(
) {

override val namespaceKind : ResourceKind<Namespace> = NamespacesOperator.KIND
private val replicasOperator = KubernetesReplicas(
NonCachingSingleResourceOperator(client),
object: ResourcesRetrieval {
override fun <T : HasMetadata> getAll(kind: ResourceKind<T>, resourcesIn: ResourcesIn): Collection<T> {
return getAllResources(kind, resourcesIn)
}
}
)

override fun getInternalResourceOperators(client: ClientAdapter<out KubernetesClient>)
: List<IResourceOperator<out HasMetadata>> {
return OperatorFactory.createKubernetes(client)
}

override fun isOpenShift() = false

override fun setReplicas(replicas: Int, replicator: Replicator) {
replicasOperator.set(replicas, replicator)
}

override fun getReplicas(resource: HasMetadata): Replicator? {
return replicasOperator.get(resource)
}

override fun getDashboardUrl(): String {
return dashboard.get()
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ import com.redhat.devtools.intellij.kubernetes.model.client.ClientAdapter
import com.redhat.devtools.intellij.kubernetes.model.client.OSClientAdapter
import com.redhat.devtools.intellij.kubernetes.model.dashboard.OpenShiftDashboard
import com.redhat.devtools.intellij.kubernetes.model.resource.IResourceOperator
import com.redhat.devtools.intellij.kubernetes.model.resource.NonCachingSingleResourceOperator
import com.redhat.devtools.intellij.kubernetes.model.resource.OperatorFactory
import com.redhat.devtools.intellij.kubernetes.model.resource.ResourceKind
import com.redhat.devtools.intellij.kubernetes.model.resource.kubernetes.KubernetesReplicas.Replicator
import com.redhat.devtools.intellij.kubernetes.model.resource.kubernetes.KubernetesReplicas.ResourcesRetrieval
import com.redhat.devtools.intellij.kubernetes.model.resource.openshift.OpenShiftReplicas
import com.redhat.devtools.intellij.kubernetes.model.resource.openshift.ProjectsOperator
import io.fabric8.kubernetes.api.model.HasMetadata
import io.fabric8.kubernetes.api.model.NamedContext
Expand All @@ -38,12 +43,29 @@ open class OpenShiftContext(
) {

override val namespaceKind = ProjectsOperator.KIND
private val replicasOperator = OpenShiftReplicas(
NonCachingSingleResourceOperator(client),
object: ResourcesRetrieval {
override fun <T : HasMetadata> getAll(kind: ResourceKind<T>, resourcesIn: IActiveContext.ResourcesIn): Collection<T> {
return getAllResources(kind, resourcesIn)
}
}
)

override fun getInternalResourceOperators(client: ClientAdapter<out OpenShiftClient>): List<IResourceOperator<out HasMetadata>> {
return OperatorFactory.createOpenShift(client)
}

override fun isOpenShift() = true

override fun setReplicas(replicas: Int, replicator: Replicator) {
replicasOperator.set(replicas, replicator)
}

override fun getReplicas(resource: HasMetadata): Replicator? {
return replicasOperator.get(resource)
}

override fun getDashboardUrl(): String {
return dashboard.get()
}
Expand Down
Loading

0 comments on commit 7919bf1

Please sign in to comment.