├── .github └── workflows │ └── main.yml ├── .gitignore ├── .run ├── All in flink-controller Integration + aws + images.run.xml ├── All in flink-controller Integration + aws.run.xml ├── All in flink-controller Integration + minio + images.run.xml ├── All in flink-controller Integration + minio.run.xml ├── All in flink-controller.run.xml ├── ExtractSchemas.run.xml ├── bootstrap run job-1.run.xml ├── bootstrap run job-2.run.xml ├── bootstrap run.run.xml ├── cluster create (1).run.xml ├── cluster create (2).run.xml ├── cluster create.run.xml ├── cluster delete.run.xml ├── cluster scale.run.xml ├── cluster start without savepoint.run.xml ├── cluster start.run.xml ├── cluster status.run.xml ├── cluster stop .run.xml ├── cluster stop without savepoint.run.xml ├── clusters list.run.xml ├── help.run.xml ├── job create 1.run.xml ├── job create 2.run.xml ├── job delete 1.run.xml ├── job delete 2.run.xml ├── job details.run.xml ├── job metrics.run.xml ├── job scale.run.xml ├── job start without savepoint.run.xml ├── job start.run.xml ├── job status.run.xml ├── job stop without savepoint.run.xml ├── job stop.run.xml ├── jobmanager metrics.run.xml ├── jobs list.run.xml ├── operator run dry-run.run.xml ├── operator run.run.xml ├── savepoint forget.run.xml ├── savepoint trigger.run.xml ├── supervisor run dry-run.run.xml ├── supervisor run.run.xml ├── taskmanager details.run.xml ├── taskmanager metrics.run.xml └── taskmanagers list.run.xml ├── Dockerfile ├── LICENSE.txt ├── MANUAL.md ├── Makefile ├── README.md ├── RELEASES.md ├── Vagrantfile ├── definitions ├── io.k8s.api.core.v1.Affinity.yaml ├── io.k8s.api.core.v1.Container.yaml ├── io.k8s.api.core.v1.ContainerPort.yaml ├── io.k8s.api.core.v1.EnvFromSource.yaml ├── io.k8s.api.core.v1.EnvVar.yaml ├── io.k8s.api.core.v1.Pod.yaml ├── io.k8s.api.core.v1.ResourceRequirements.yaml ├── io.k8s.api.core.v1.SecurityContext.yaml ├── io.k8s.api.core.v1.Toleration.yaml ├── io.k8s.api.core.v1.TopologySpreadConstraint.yaml ├── io.k8s.api.core.v1.Volume.yaml └── io.k8s.api.core.v1.VolumeMount.yaml ├── example ├── README.md ├── docker │ └── Dockerfile └── helm │ ├── example │ ├── Chart.yaml │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ ├── flinkproperties.yaml │ │ └── jobproperties.yaml │ └── values.yaml │ └── minio │ ├── Chart.yaml │ ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── deployment.yaml │ └── service.yaml │ └── values.yaml ├── graphs ├── flink-cluster.dot ├── flink-cluster.png ├── flink-job.dot ├── flink-job.png ├── flink-operator.dot ├── flink-operator.png └── update.sh ├── helm ├── flink-controller-crd │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── flinkcluster.yaml │ │ ├── flinkdeployment.yaml │ │ └── flinkjob.yaml │ └── values.yaml ├── flink-controller-operator │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ └── service.yaml │ └── values.yaml └── flink-controller-roles │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ └── rbac.yaml │ └── values.yaml ├── integration ├── cluster-spec.json ├── deployment-0.yaml ├── deployment-1.yaml ├── deployment-2.yaml ├── deployment-3.yaml ├── docker │ ├── flink │ │ └── Dockerfile │ └── jobs │ │ └── Dockerfile ├── helm │ ├── jobs │ │ ├── .helmignore │ │ ├── Chart.yaml │ │ ├── templates │ │ │ ├── NOTES.txt │ │ │ ├── _helpers.tpl │ │ │ ├── flinkproperties.yaml │ │ │ └── jobproperties.yaml │ │ └── values.yaml │ └── minio │ │ ├── Chart.yaml │ │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ └── service.yaml │ │ └── values.yaml └── job-spec.json ├── maven-version-rules.xml ├── pipeline ├── docker-build-images.sh ├── docker-login.sh ├── docker-push-image.sh ├── docker-update-latest.sh ├── install-docker.sh ├── install-helm.sh ├── install-java.sh ├── install-kubectl.sh ├── install-minikube.sh ├── print-dependencies.sh ├── print-java-version.sh ├── run-integration-test.sh ├── run-integration-tests.sh ├── run-minikube.sh └── run-tests.sh ├── pom.xml ├── schemas ├── flinkcluster-schema.json ├── flinkdeployment-schema.json └── flinkjob-schema.json ├── scripts ├── registry │ ├── README.md │ ├── docker-registry-setup.sh │ └── docker-registry-ssl.conf ├── run-bootstrap.sh ├── run-operator.sh └── run-supervisor.sh ├── secrets.sh ├── src ├── main │ ├── java │ │ └── com │ │ │ └── nextbreakpoint │ │ │ └── flink │ │ │ └── controller │ │ │ └── k8s │ │ │ ├── factory │ │ │ ├── BootstrapResourcesDefaultFactory.java │ │ │ ├── BootstrapResourcesFactory.java │ │ │ ├── ClusterResourcesDefaultFactory.java │ │ │ ├── ClusterResourcesFactory.java │ │ │ ├── DeploymentResourcesDefaultFactory.java │ │ │ ├── DeploymentResourcesFactory.java │ │ │ ├── SupervisorResourcesDefaultFactory.java │ │ │ └── SupervisorResourcesFactory.java │ │ │ └── kube │ │ │ └── Register.java │ ├── kotlin │ │ └── com │ │ │ └── nextbreakpoint │ │ │ └── flink │ │ │ └── controller │ │ │ ├── cli │ │ │ ├── Main.kt │ │ │ ├── command │ │ │ │ ├── ClusterCreate.kt │ │ │ │ ├── ClusterDelete.kt │ │ │ │ ├── ClusterScale.kt │ │ │ │ ├── ClusterStart.kt │ │ │ │ ├── ClusterStatus.kt │ │ │ │ ├── ClusterStop.kt │ │ │ │ ├── ClusterUpdate.kt │ │ │ │ ├── ClustersList.kt │ │ │ │ ├── DeploymentCreate.kt │ │ │ │ ├── DeploymentDelete.kt │ │ │ │ ├── DeploymentStatus.kt │ │ │ │ ├── DeploymentUpdate.kt │ │ │ │ ├── DeploymentsList.kt │ │ │ │ ├── JobCreate.kt │ │ │ │ ├── JobDelete.kt │ │ │ │ ├── JobDetails.kt │ │ │ │ ├── JobManagerMetrics.kt │ │ │ │ ├── JobMetrics.kt │ │ │ │ ├── JobScale.kt │ │ │ │ ├── JobStart.kt │ │ │ │ ├── JobStatus.kt │ │ │ │ ├── JobStop.kt │ │ │ │ ├── JobUpdate.kt │ │ │ │ ├── JobsList.kt │ │ │ │ ├── LaunchBootstrap.kt │ │ │ │ ├── LaunchOperator.kt │ │ │ │ ├── LaunchSupervisor.kt │ │ │ │ ├── SavepointForget.kt │ │ │ │ ├── SavepointTrigger.kt │ │ │ │ ├── TaskManagerDetails.kt │ │ │ │ ├── TaskManagerMetrics.kt │ │ │ │ └── TaskManagersList.kt │ │ │ ├── core │ │ │ │ ├── ClusterCommand.kt │ │ │ │ ├── DeploymentCommand.kt │ │ │ │ ├── HttpUtils.kt │ │ │ │ ├── JobCommand.kt │ │ │ │ ├── LaunchCommand.kt │ │ │ │ └── OperatorCommand.kt │ │ │ └── factory │ │ │ │ ├── CommandDefaultFactory.kt │ │ │ │ ├── CommandFactory.kt │ │ │ │ ├── WebClientDefaultFactory.kt │ │ │ │ └── WebClientFactory.kt │ │ │ ├── common │ │ │ ├── Action.kt │ │ │ ├── BootstrapOptions.kt │ │ │ ├── ClusterSelector.kt │ │ │ ├── ClusterStatus.kt │ │ │ ├── ConnectionConfig.kt │ │ │ ├── DeleteOptions.kt │ │ │ ├── DeploymentSelector.kt │ │ │ ├── FlinkAddress.kt │ │ │ ├── FlinkOptions.kt │ │ │ ├── JobManagerStats.kt │ │ │ ├── JobSelector.kt │ │ │ ├── JobStats.kt │ │ │ ├── JobStatus.kt │ │ │ ├── OperatorOptions.kt │ │ │ ├── RescalePolicy.kt │ │ │ ├── RescaleStatus.kt │ │ │ ├── ResourceStatus.kt │ │ │ ├── RestartPolicy.kt │ │ │ ├── RunJarOptions.kt │ │ │ ├── RunnerOptions.kt │ │ │ ├── SavepointMode.kt │ │ │ ├── SavepointOptions.kt │ │ │ ├── SavepointRequest.kt │ │ │ ├── SavepointStatus.kt │ │ │ ├── ScaleClusterOptions.kt │ │ │ ├── ScaleJobOptions.kt │ │ │ ├── ServerConfig.kt │ │ │ ├── StartOptions.kt │ │ │ ├── StopOptions.kt │ │ │ ├── SupervisorOptions.kt │ │ │ ├── TaskManagerId.kt │ │ │ └── TaskManagerStats.kt │ │ │ ├── k8s │ │ │ ├── bootstrap │ │ │ │ ├── Bootstrap.kt │ │ │ │ └── BootstrapRunner.kt │ │ │ ├── common │ │ │ │ ├── FlinkClient.kt │ │ │ │ ├── FlinkClientException.kt │ │ │ │ ├── FlinkClusterAnnotations.kt │ │ │ │ ├── FlinkClusterConfiguration.kt │ │ │ │ ├── FlinkClusterStatus.kt │ │ │ │ ├── FlinkDeploymentStatus.kt │ │ │ │ ├── FlinkJobAnnotations.kt │ │ │ │ ├── FlinkJobConfiguration.kt │ │ │ │ ├── FlinkJobStatus.kt │ │ │ │ ├── KubeClient.kt │ │ │ │ ├── NotFoundException.kt │ │ │ │ ├── Resource.kt │ │ │ │ ├── Task.kt │ │ │ │ ├── Time.kt │ │ │ │ └── Timeout.kt │ │ │ ├── controller │ │ │ │ ├── Controller.kt │ │ │ │ ├── action │ │ │ │ │ ├── BatchJobCreate.kt │ │ │ │ │ ├── BatchJobDelete.kt │ │ │ │ │ ├── ClusterIsReady.kt │ │ │ │ │ ├── ClusterListJars.kt │ │ │ │ │ ├── ClusterRemoveJars.kt │ │ │ │ │ ├── ClusterRunJar.kt │ │ │ │ │ ├── ClusterStopJobs.kt │ │ │ │ │ ├── ClusterUploadJar.kt │ │ │ │ │ ├── DeploymentCreate.kt │ │ │ │ │ ├── DeploymentDelete.kt │ │ │ │ │ ├── FlinkClusterCreate.kt │ │ │ │ │ ├── FlinkClusterDelete.kt │ │ │ │ │ ├── FlinkClusterGetStatus.kt │ │ │ │ │ ├── FlinkClusterUpdate.kt │ │ │ │ │ ├── FlinkDeploymentCreate.kt │ │ │ │ │ ├── FlinkDeploymentDelete.kt │ │ │ │ │ ├── FlinkDeploymentGetStatus.kt │ │ │ │ │ ├── FlinkDeploymentUpdate.kt │ │ │ │ │ ├── FlinkJobCreate.kt │ │ │ │ │ ├── FlinkJobDelete.kt │ │ │ │ │ ├── FlinkJobGetStatus.kt │ │ │ │ │ ├── FlinkJobUpdate.kt │ │ │ │ │ ├── JobCancel.kt │ │ │ │ │ ├── JobDetails.kt │ │ │ │ │ ├── JobGetStatus.kt │ │ │ │ │ ├── JobManagerMetrics.kt │ │ │ │ │ ├── JobMetrics.kt │ │ │ │ │ ├── JobStop.kt │ │ │ │ │ ├── PodCreate.kt │ │ │ │ │ ├── PodDelete.kt │ │ │ │ │ ├── RequestClusterScale.kt │ │ │ │ │ ├── RequestClusterStart.kt │ │ │ │ │ ├── RequestClusterStop.kt │ │ │ │ │ ├── RequestJobScale.kt │ │ │ │ │ ├── RequestJobStart.kt │ │ │ │ │ ├── RequestJobStop.kt │ │ │ │ │ ├── RequestSavepointForget.kt │ │ │ │ │ ├── RequestSavepointTrigger.kt │ │ │ │ │ ├── SavepointQuery.kt │ │ │ │ │ ├── SavepointTrigger.kt │ │ │ │ │ ├── ServiceCreate.kt │ │ │ │ │ ├── ServiceDelete.kt │ │ │ │ │ ├── TaskManagerDetails.kt │ │ │ │ │ ├── TaskManagerMetrics.kt │ │ │ │ │ ├── TaskManagersList.kt │ │ │ │ │ └── TaskManagersStatus.kt │ │ │ │ └── core │ │ │ │ │ ├── ClusterAction.kt │ │ │ │ │ ├── ClusterContext.kt │ │ │ │ │ ├── DeploymentContext.kt │ │ │ │ │ ├── JobAction.kt │ │ │ │ │ ├── JobContext.kt │ │ │ │ │ ├── Result.kt │ │ │ │ │ └── ResultStatus.kt │ │ │ ├── operator │ │ │ │ ├── Operator.kt │ │ │ │ ├── OperatorRunner.kt │ │ │ │ └── core │ │ │ │ │ ├── Adapter.kt │ │ │ │ │ ├── Cache.kt │ │ │ │ │ ├── DeploymentManager.kt │ │ │ │ │ ├── JobManager.kt │ │ │ │ │ ├── OperatorController.kt │ │ │ │ │ ├── SupervisorManager.kt │ │ │ │ │ └── SupervisorResources.kt │ │ │ └── supervisor │ │ │ │ ├── Supervisor.kt │ │ │ │ ├── SupervisorRunner.kt │ │ │ │ ├── core │ │ │ │ ├── Adapter.kt │ │ │ │ ├── Cache.kt │ │ │ │ ├── ClusterController.kt │ │ │ │ ├── ClusterManager.kt │ │ │ │ ├── ClusterResources.kt │ │ │ │ ├── JobController.kt │ │ │ │ ├── JobManager.kt │ │ │ │ └── JobResources.kt │ │ │ │ └── task │ │ │ │ ├── ClusterOnInitialize.kt │ │ │ │ ├── ClusterOnStarted.kt │ │ │ │ ├── ClusterOnStarting.kt │ │ │ │ ├── ClusterOnStopped.kt │ │ │ │ ├── ClusterOnStopping.kt │ │ │ │ ├── ClusterOnTerminated.kt │ │ │ │ ├── JobOnInitialise.kt │ │ │ │ ├── JobOnStarted.kt │ │ │ │ ├── JobOnStarting.kt │ │ │ │ ├── JobOnStopped.kt │ │ │ │ ├── JobOnStopping.kt │ │ │ │ └── JobOnTerminated.kt │ │ │ └── vertex │ │ │ ├── MonitoringVerticle.kt │ │ │ ├── OperatorVerticle.kt │ │ │ ├── SupervisorVerticle.kt │ │ │ └── core │ │ │ ├── ClusterCommand.kt │ │ │ ├── DeploymentCommand.kt │ │ │ ├── JobCommand.kt │ │ │ └── Timeout.kt │ ├── lombok │ │ └── com │ │ │ └── nextbreakpoint │ │ │ └── flink │ │ │ └── controller │ │ │ └── k8s │ │ │ └── crd │ │ │ ├── V1BootstrapSpec.java │ │ │ ├── V1FlinkCluster.java │ │ │ ├── V1FlinkClusterDigest.java │ │ │ ├── V1FlinkClusterList.java │ │ │ ├── V1FlinkClusterSpec.java │ │ │ ├── V1FlinkClusterStatus.java │ │ │ ├── V1FlinkDeployment.java │ │ │ ├── V1FlinkDeploymentDigest.java │ │ │ ├── V1FlinkDeploymentJobDigest.java │ │ │ ├── V1FlinkDeploymentJobSpec.java │ │ │ ├── V1FlinkDeploymentList.java │ │ │ ├── V1FlinkDeploymentSpec.java │ │ │ ├── V1FlinkDeploymentStatus.java │ │ │ ├── V1FlinkJob.java │ │ │ ├── V1FlinkJobDigest.java │ │ │ ├── V1FlinkJobList.java │ │ │ ├── V1FlinkJobSpec.java │ │ │ ├── V1FlinkJobStatus.java │ │ │ ├── V1JobManagerSpec.java │ │ │ ├── V1RestartSpec.java │ │ │ ├── V1RuntimeSpec.java │ │ │ ├── V1SavepointSpec.java │ │ │ ├── V1SupervisorSpec.java │ │ │ └── V1TaskManagerSpec.java │ └── resources │ │ ├── META-INF │ │ └── LICENSE.txt │ │ ├── application.properties │ │ └── log4j2.xml └── test │ ├── java │ └── com │ │ └── nextbreakpoint │ │ └── flink │ │ └── controller │ │ └── testing │ │ └── TestFactory.java │ ├── kotlin │ └── com │ │ └── nextbreakpoint │ │ └── flink │ │ └── controller │ │ ├── integration │ │ ├── EnsureBehaviourIT.kt │ │ ├── IntegrationSetup.kt │ │ └── TestRecording.kt │ │ ├── k8s │ │ ├── common │ │ │ ├── FlinkClusterAnnotationsTest.kt │ │ │ ├── FlinkClusterStatusTest.kt │ │ │ ├── FlinkJobConfigurationTest.kt │ │ │ └── FlinkJobStatusTest.kt │ │ ├── controller │ │ │ ├── action │ │ │ │ ├── BatchJobCreateTest.kt │ │ │ │ ├── BatchJobDeleteTest.kt │ │ │ │ ├── ClusterIsReadyTest.kt │ │ │ │ ├── ClusterRemoveJarsTest.kt │ │ │ │ ├── ClusterStopJobsTest.kt │ │ │ │ ├── DeploymentCreateTest.kt │ │ │ │ ├── DeploymentDeleteTest.kt │ │ │ │ ├── FlinkClusterCreateTest.kt │ │ │ │ ├── FlinkClusterDeleteTest.kt │ │ │ │ ├── FlinkClusterGetStatusTest.kt │ │ │ │ ├── FlinkJobCreateTest.kt │ │ │ │ ├── FlinkJobDeleteTest.kt │ │ │ │ ├── FlinkJobGetStatusTest.kt │ │ │ │ ├── JobCancelTest.kt │ │ │ │ ├── JobDetailsTest.kt │ │ │ │ ├── JobManagerMetricsTest.kt │ │ │ │ ├── JobMetricsTest.kt │ │ │ │ ├── JobStatusTest.kt │ │ │ │ ├── JobStopTest.kt │ │ │ │ ├── PodCreateTest.kt │ │ │ │ ├── PodDeleteTest.kt │ │ │ │ ├── RequestClusterScaleTest.kt │ │ │ │ ├── RequestClusterStartTest.kt │ │ │ │ ├── RequestClusterStopTest.kt │ │ │ │ ├── RequestJobScaleTest.kt │ │ │ │ ├── RequestJobStartTest.kt │ │ │ │ ├── RequestJobStopTest.kt │ │ │ │ ├── RequestSavepointForgetTest.kt │ │ │ │ ├── RequestSavepointTriggerTest.kt │ │ │ │ ├── SavepointQueryTest.kt │ │ │ │ ├── SavepointTriggerTest.kt │ │ │ │ ├── ServiceCreateTest.kt │ │ │ │ ├── ServiceDeleteTest.kt │ │ │ │ ├── TaskManagerDetailsTest.kt │ │ │ │ ├── TaskManagerMetricsTest.kt │ │ │ │ ├── TaskManagersListTest.kt │ │ │ │ └── TaskManagersStatusTest.kt │ │ │ └── core │ │ │ │ └── ClusterActionResultTest.kt │ │ ├── factory │ │ │ ├── BootstrapResourcesDefaultFactoryTest.kt │ │ │ └── ClusterResourcesDefaultFactoryTest.kt │ │ └── supervisor │ │ │ ├── SupervisorTest.kt │ │ │ ├── core │ │ │ ├── CacheTest.kt │ │ │ ├── ClusterControllerTest.kt │ │ │ ├── ClusterManagerTest.kt │ │ │ ├── JobControllerTest.kt │ │ │ └── JobManagerTest.kt │ │ │ └── task │ │ │ ├── ClusterOnInitializeTest.kt │ │ │ ├── ClusterOnStartedTest.kt │ │ │ ├── ClusterOnStartingTest.kt │ │ │ ├── ClusterOnStoppedTest.kt │ │ │ ├── ClusterOnStoppingTest.kt │ │ │ ├── ClusterOnTerminatedTest.kt │ │ │ ├── JobOnInitializeTest.kt │ │ │ ├── JobOnStartedTest.kt │ │ │ ├── JobOnStartingTest.kt │ │ │ ├── JobOnStoppedTest.kt │ │ │ ├── JobOnStoppingTest.kt │ │ │ └── JobOnTerminatedTest.kt │ │ ├── testing │ │ └── KotlinMockito.kt │ │ └── utility │ │ └── ExtractSchemas.kt │ └── resources │ ├── cluster.json │ ├── job.json │ └── mockito-extensions │ └── org.mockito.plugins.MockMaker ├── toolchains-docker.xml ├── toolchains-linux.xml ├── toolchains-osx.xml └── toolchains-pipeline.xml /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .idea 3 | target 4 | dependency-reduced-pom.xml 5 | docker-registry.yaml 6 | helm/charts 7 | secrets 8 | .vertx 9 | tmp 10 | config 11 | .vagrant 12 | ubuntu-bionic-18.04-cloudimg-console.log 13 | lombok.config 14 | reports 15 | -------------------------------------------------------------------------------- /.run/All in flink-controller Integration + aws + images.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 24 | -------------------------------------------------------------------------------- /.run/All in flink-controller Integration + aws.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 24 | -------------------------------------------------------------------------------- /.run/All in flink-controller Integration + minio + images.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 22 | -------------------------------------------------------------------------------- /.run/All in flink-controller Integration + minio.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 22 | -------------------------------------------------------------------------------- /.run/All in flink-controller.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 18 | -------------------------------------------------------------------------------- /.run/ExtractSchemas.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/bootstrap run job-1.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/bootstrap run job-2.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/bootstrap run.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/cluster create (1).run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/cluster create (2).run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/cluster create.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/cluster delete.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/cluster scale.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/cluster start without savepoint.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/cluster start.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/cluster status.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/cluster stop .run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/cluster stop without savepoint.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/clusters list.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/help.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/job create 1.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/job create 2.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/job delete 1.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/job delete 2.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/job details.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/job metrics.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/job scale.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/job start without savepoint.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/job start.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/job status.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/job stop without savepoint.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/job stop.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/jobmanager metrics.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/jobs list.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/operator run dry-run.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /.run/operator run.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /.run/savepoint forget.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/savepoint trigger.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/supervisor run dry-run.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | -------------------------------------------------------------------------------- /.run/supervisor run.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | -------------------------------------------------------------------------------- /.run/taskmanager details.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/taskmanager metrics.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /.run/taskmanagers list.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM maven:3.9-eclipse-temurin-21-jammy AS build 2 | ADD . /src 3 | WORKDIR /src 4 | RUN mvn -t toolchains-docker.xml -Pdistribution clean package 5 | 6 | #FROM ghcr.io/graalvm/native-image-community:23 as native-image 7 | #COPY --from=build /src/build/libs/* /build/libs/ 8 | #COPY --from=build /src/build/.classpath /build/.classpath 9 | #WORKDIR / 10 | #RUN native-image --verbose -J-Xmx4G -cp $(cat /build/.classpath) -H:+UnlockExperimentalVMOptions -H:+StaticExecutableWithDynamicLibC -H:Name=flinkctl -H:Class=com.nextbreakpoint.flink.controller.cli.Main 11 | 12 | FROM gcr.io/distroless/base 13 | COPY --from=build /src/target/jpackage/flinkctl /flinkctl 14 | EXPOSE 4444 8080 15 | ENTRYPOINT ["/flinkctl/bin/flinkctl"] 16 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019-2024, Andrea Medeghini 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the copyright holder nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: build 2 | build: 3 | mvn package 4 | 5 | .PHONY: clean 6 | clean: 7 | mvn clean 8 | 9 | .PHONY: test 10 | test: 11 | mvn test 12 | 13 | .PHONY: verify 14 | verify: 15 | BUILD_IMAGES=true OPERATOR_HOST=$$(minikube ip) mvn verify -Dtest=com.nextbreakpoint.flink.controller.integration.EnsureBehaviourIT 16 | 17 | .PHONY: verify-skip-image 18 | verify-skip-image: 19 | BUILD_IMAGES=false OPERATOR_HOST=$$(minikube ip) mvn verify -Dtest=com.nextbreakpoint.flink.controller.integration.EnsureBehaviourIT 20 | 21 | .PHONY: package 22 | package: 23 | mvn package -DskipTests=true 24 | 25 | .PHONY: install 26 | install: 27 | mvn install -DskipTests=true 28 | 29 | .PHONY: package-shaded 30 | package-shaded: 31 | mvn package -DskipTests=true -Pshaded 32 | 33 | .PHONY: package-distribution 34 | package-distribution: 35 | mvn package -DskipTests=true -Pdistribution 36 | 37 | .PHONY: build-image 38 | build-image: 39 | eval $$(minikube docker-env) && docker build -t nextbreakpoint/flinkctl:1.5.0 . 40 | 41 | .PHONY: release 42 | release: 43 | #mvn -Dchannel=ossrh clean deploy 44 | mvn clean package -DskipTests=true -Pshaded 45 | mvn -Dchannel=github de.jutzig:github-release-plugin:release 46 | 47 | .PHONY: version 48 | version: 49 | @echo $(shell mvn -q help:evaluate -Dexpression=project.version -DforceStdout) 50 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant.configure(2) do |config| 2 | unless Vagrant.has_plugin?("vagrant-disksize") 3 | raise Vagrant::Errors::VagrantError.new, "vagrant-disksize plugin is missing. Please install it using 'vagrant plugin install vagrant-disksize' and rerun 'vagrant up'" 4 | end 5 | 6 | if Vagrant.has_plugin?("vagrant-disksize") 7 | config.disksize.size = '17GB' 8 | end 9 | 10 | config.vm.define "integration" do |s| 11 | s.ssh.forward_agent = true 12 | s.vm.box = "ubuntu/bionic64" 13 | s.vm.hostname = "minikube" 14 | s.vm.network "private_network", 15 | ip: "192.168.1.20", 16 | netmask: "255.255.255.0", 17 | auto_config: true 18 | s.vm.provision :shell, 19 | path: "pipeline/install-docker.sh", 20 | privileged: false 21 | s.vm.provision :shell, 22 | path: "pipeline/install-minikube.sh", 23 | privileged: false 24 | s.vm.provision :shell, 25 | path: "pipeline/install-kubectl.sh", 26 | privileged: false 27 | s.vm.provision :shell, 28 | path: "pipeline/install-helm.sh", 29 | privileged: false 30 | s.vm.provision :shell, 31 | path: "pipeline/install-java.sh", 32 | privileged: false 33 | s.vm.provider "virtualbox" do |v| 34 | v.name = "integration" 35 | v.cpus = 2 36 | v.memory = 7168 37 | v.gui = false 38 | v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] 39 | #v.customize ["modifyvm", :id, "--natdnsproxy1", "on"] 40 | end 41 | end 42 | 43 | end 44 | -------------------------------------------------------------------------------- /definitions/io.k8s.api.core.v1.ContainerPort.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | description: "ContainerPort represents a network port in a single container." 3 | properties: 4 | containerPort: 5 | description: "Number of port to expose on the pod's IP address. This must be a\ 6 | \ valid port number, 0 < x < 65536." 7 | format: "int32" 8 | type: "integer" 9 | hostIP: 10 | description: "What host IP to bind the external port to." 11 | type: "string" 12 | hostPort: 13 | description: "Number of port to expose on the host. If specified, this must be\ 14 | \ a valid port number, 0 < x < 65536. If HostNetwork is specified, this must\ 15 | \ match ContainerPort. Most containers do not need this." 16 | format: "int32" 17 | type: "integer" 18 | name: 19 | description: "If specified, this must be an IANA_SVC_NAME and unique within the\ 20 | \ pod. Each named port in a pod must have a unique name. Name for the port that\ 21 | \ can be referred to by services." 22 | type: "string" 23 | protocol: 24 | description: "Protocol for port. Must be UDP, TCP, or SCTP. Defaults to \"TCP\"\ 25 | ." 26 | type: "string" 27 | required: 28 | - "containerPort" 29 | type: "object" 30 | -------------------------------------------------------------------------------- /example/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG base_image="nextbreakpoint/flinkctl:1.5.0" 2 | FROM ubuntu:latest AS download 3 | ARG dummies_version="0.0.6" 4 | RUN apt update -y && apt install -y curl 5 | RUN curl https://github.com/nextbreakpoint/flink-dummies/releases/download/v${dummies_version}/com.nextbreakpoint.flink.dummies-${dummies_version}.jar -L -o /com.nextbreakpoint.flink.dummies.jar 6 | FROM ${base_image} 7 | COPY --from=download /com.nextbreakpoint.flink.dummies.jar / 8 | -------------------------------------------------------------------------------- /example/helm/example/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | appVersion: "1.0" 3 | description: A Helm chart for installing Flink cluster and jobs 4 | name: example 5 | version: 1.0 6 | -------------------------------------------------------------------------------- /example/helm/example/templates/NOTES.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextbreakpoint/flink-controller/72f4ca978d417c4bc30fa69cae6f4f3fa8e53543/example/helm/example/templates/NOTES.txt -------------------------------------------------------------------------------- /example/helm/example/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "example.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "example.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "example.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | -------------------------------------------------------------------------------- /example/helm/example/templates/jobproperties.yaml: -------------------------------------------------------------------------------- 1 | {{- $fullname := include "example.fullname" . -}} 2 | {{- $name := include "example.name" . -}} 3 | {{- $chart := include "example.chart" . -}} 4 | {{- $root := . }} 5 | apiVersion: v1 6 | kind: ConfigMap 7 | metadata: 8 | name: {{ $name }}-job-properties-v1 9 | namespace: {{ $root.Release.Namespace | quote }} 10 | labels: 11 | chart: {{ $chart }} 12 | release: {{ $root.Release.Name }} 13 | heritage: {{ $root.Release.Service }} 14 | data: 15 | measurement.properties: | 16 | job.name: temperature-measurement 17 | log.verbosity: 2 18 | watermark.strategy.max-out-of-orderness: 5000 19 | watermark.strategy.idle-timeout: 30000 20 | source.max-delay: 5000 21 | source.max-count: 0 22 | bucket.output-path: s3a://${BUCKET_NAME}/temperature-measurement 23 | bucket.check-interval: 30000 24 | bucket.rollover-interval: 300000 25 | bucket.inactivity-interval: 300000 26 | bucket.max-part-size-mb: 1024 27 | window.size: 60000 28 | window.slide: 60000 29 | flink.rest.bind-port: 8081 30 | flink.parallelism.default: 4 31 | flink.pipeline.max-parallelism: 128 32 | flink.pipeline.auto-watermark-interval: 10000 33 | flink.pipeline.operator-chaining.enabled: true 34 | flink.state.backend.type: hashmap 35 | flink.execution.checkpointing.interval: 300000 36 | flink.restart-strategy.type: disable 37 | #flink.restart-strategy.type: fixed-delay 38 | #flink.restart-strategy.fixed-delay.attempts: 3 39 | #flink.restart-strategy.fixed-delay.delay: 60000 40 | -------------------------------------------------------------------------------- /example/helm/example/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | s3BucketName: nextbreakpoint-example 6 | s3Endpoint: http://minio-headless.minio:9000 7 | s3PathStyleAccess: "true" 8 | s3AccessKey: minioaccesskey 9 | s3SecretKey: miniosecretkey 10 | 11 | flinkVersion: "1.20.0" 12 | 13 | runtime: 14 | pullPolicy: IfNotPresent 15 | image: apache/flink:1.20.0-scala_2.12-java11 16 | 17 | supervisor: 18 | pullPolicy: IfNotPresent 19 | rescalePolicy: JobParallelism 20 | rescaleDelay: 10 21 | taskTimeout: 180 22 | pollingInterval: 5 23 | replicas: 1 24 | 25 | jobManager: 26 | serviceMode: ClusterIP 27 | 28 | taskManager: 29 | taskSlots: 1 30 | 31 | jobs: 32 | pullPolicy: IfNotPresent 33 | image: example/jobs:latest 34 | example: 35 | restartPolicy: Always 36 | savepointMode: Automatic 37 | savepointInterval: 600 38 | jobParallelism: 1 39 | restartDelay: 30 40 | restartTimeout: 120 41 | 42 | taskManagers: 43 | -------------------------------------------------------------------------------- /example/helm/minio/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | appVersion: "1.0" 3 | description: A Helm chart for installing Minio 4 | name: minio 5 | version: 0.1.0 6 | -------------------------------------------------------------------------------- /example/helm/minio/templates/NOTES.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextbreakpoint/flink-controller/72f4ca978d417c4bc30fa69cae6f4f3fa8e53543/example/helm/minio/templates/NOTES.txt -------------------------------------------------------------------------------- /example/helm/minio/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "minio.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "minio.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "minio.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | -------------------------------------------------------------------------------- /example/helm/minio/templates/service.yaml: -------------------------------------------------------------------------------- 1 | {{- $fullname := include "minio.fullname" . -}} 2 | {{- $name := include "minio.name" . -}} 3 | {{- $chart := include "minio.chart" . -}} 4 | {{- $root := . }} 5 | apiVersion: v1 6 | kind: Service 7 | metadata: 8 | name: {{ $fullname }}-headless 9 | labels: 10 | app: {{ $name }} 11 | chart: {{ $chart }} 12 | release: {{ $root.Release.Name }} 13 | heritage: {{ $root.Release.Service }} 14 | spec: 15 | clusterIP: None 16 | ports: 17 | - port: 9000 18 | targetPort: http 19 | protocol: TCP 20 | name: minio 21 | - port: 9001 22 | targetPort: http 23 | protocol: TCP 24 | name: minio-console 25 | selector: 26 | app: {{ $name }} 27 | release: {{ $root.Release.Name }} 28 | --- 29 | apiVersion: v1 30 | kind: Service 31 | metadata: 32 | name: {{ $fullname }} 33 | labels: 34 | app: {{ $name }} 35 | chart: {{ $chart }} 36 | release: {{ $root.Release.Name }} 37 | heritage: {{ $root.Release.Service }} 38 | external: "false" 39 | spec: 40 | type: ClusterIP 41 | ports: 42 | - port: 9000 43 | targetPort: http 44 | protocol: TCP 45 | name: minio 46 | - port: 9001 47 | targetPort: http 48 | protocol: TCP 49 | name: minio-console 50 | selector: 51 | app: {{ $name }} 52 | release: {{ $root.Release.Name }} 53 | -------------------------------------------------------------------------------- /example/helm/minio/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for kafka. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | minio: 6 | accessKey: "minioaccesskey" 7 | secretKey: "miniosecretkey" 8 | -------------------------------------------------------------------------------- /graphs/flink-cluster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextbreakpoint/flink-controller/72f4ca978d417c4bc30fa69cae6f4f3fa8e53543/graphs/flink-cluster.png -------------------------------------------------------------------------------- /graphs/flink-job.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextbreakpoint/flink-controller/72f4ca978d417c4bc30fa69cae6f4f3fa8e53543/graphs/flink-job.png -------------------------------------------------------------------------------- /graphs/flink-operator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextbreakpoint/flink-controller/72f4ca978d417c4bc30fa69cae6f4f3fa8e53543/graphs/flink-operator.png -------------------------------------------------------------------------------- /graphs/update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | dot -Tpng flink-operator.dot > flink-operator.png 4 | dot -Tpng flink-cluster.dot > flink-cluster.png 5 | dot -Tpng flink-job.dot > flink-job.png 6 | -------------------------------------------------------------------------------- /helm/flink-controller-crd/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /helm/flink-controller-crd/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | appVersion: "1.0" 3 | description: A Helm chart for installing Flink Kubernetes Toolbox CRDs 4 | name: flink-controller-crd 5 | version: 1.5.0 6 | -------------------------------------------------------------------------------- /helm/flink-controller-crd/templates/NOTES.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextbreakpoint/flink-controller/72f4ca978d417c4bc30fa69cae6f4f3fa8e53543/helm/flink-controller-crd/templates/NOTES.txt -------------------------------------------------------------------------------- /helm/flink-controller-crd/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "flink-controller.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "flink-controller.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "flink-controller.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | -------------------------------------------------------------------------------- /helm/flink-controller-crd/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | -------------------------------------------------------------------------------- /helm/flink-controller-operator/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /helm/flink-controller-operator/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | appVersion: "1.0" 3 | description: A Helm chart for installing Flink Kubernetes Toolbox operator 4 | name: flink-controller-operator 5 | version: 1.5.0 6 | -------------------------------------------------------------------------------- /helm/flink-controller-operator/templates/NOTES.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextbreakpoint/flink-controller/72f4ca978d417c4bc30fa69cae6f4f3fa8e53543/helm/flink-controller-operator/templates/NOTES.txt -------------------------------------------------------------------------------- /helm/flink-controller-operator/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "flink-controller.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "flink-controller.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "flink-controller.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | -------------------------------------------------------------------------------- /helm/flink-controller-operator/templates/service.yaml: -------------------------------------------------------------------------------- 1 | {{- $fullname := include "flink-controller.fullname" . -}} 2 | {{- $name := include "flink-controller.name" . -}} 3 | {{- $chart := include "flink-controller.chart" . -}} 4 | {{- $root := . }} 5 | apiVersion: v1 6 | kind: Service 7 | metadata: 8 | name: {{ $root.Values.name | default "flink-operator" | quote }} 9 | namespace: {{ $root.Release.Namespace | quote }} 10 | labels: 11 | app: {{ $root.Values.name | default "flink-operator" | quote }} 12 | chart: {{ $chart }} 13 | release: {{ $root.Release.Name }} 14 | heritage: {{ $root.Release.Service }} 15 | spec: 16 | type: {{ $root.Values.serviceType | default "ClusterIP" }} 17 | ports: 18 | - port: {{ $root.Values.controlPort | default 4444 }} 19 | {{- if $root.Values.serviceNodePort}} 20 | nodePort: {{ $root.Values.serviceNodePort }} 21 | {{- end}} 22 | targetPort: control 23 | protocol: TCP 24 | name: {{ $root.Values.controlPortName | default "control" }} 25 | - port: {{ $root.Values.monitorPort | default 8080 }} 26 | targetPort: monitor 27 | protocol: TCP 28 | name: {{ $root.Values.monitorPortName | default "monitor" }} 29 | selector: 30 | app: {{ $root.Values.name | default "flink-operator" | quote }} 31 | -------------------------------------------------------------------------------- /helm/flink-controller-operator/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | image: 6 | repository: nextbreakpoint/flinkctl 7 | tag: 1.5.0 8 | pullPolicy: Always 9 | pullSecrets: 10 | 11 | annotations: 12 | 13 | strategy: 14 | type: Recreate 15 | 16 | resources: 17 | requests: 18 | memory: "256Mi" 19 | cpu: "0.1" 20 | limits: 21 | memory: "256Mi" 22 | cpu: "1.0" 23 | 24 | secretName: 25 | 26 | serviceAccount: flink-operator 27 | 28 | serviceType: ClusterIP 29 | serviceNodePort: 30 | 31 | keystore: 32 | pathKey: keystore.jks 33 | secretKey: keystore-secret 34 | 35 | truststore: 36 | pathKey: truststore.jks 37 | secretKey: truststore-secret 38 | 39 | taskTimeout: 120 40 | pollingInterval: 10 41 | -------------------------------------------------------------------------------- /helm/flink-controller-roles/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /helm/flink-controller-roles/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | appVersion: "1.0" 3 | description: A Helm chart for installing default roles 4 | name: flink-controller-roles 5 | version: 1.5.0 6 | -------------------------------------------------------------------------------- /helm/flink-controller-roles/templates/NOTES.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextbreakpoint/flink-controller/72f4ca978d417c4bc30fa69cae6f4f3fa8e53543/helm/flink-controller-roles/templates/NOTES.txt -------------------------------------------------------------------------------- /helm/flink-controller-roles/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "flink-controller.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "flink-controller.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "flink-controller.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | -------------------------------------------------------------------------------- /helm/flink-controller-roles/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | -------------------------------------------------------------------------------- /integration/docker/flink/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG flink_version="1.20.0" 2 | ARG scala_version="2.12" 3 | FROM apache/flink:${flink_version}-scala_${scala_version}-java11 4 | -------------------------------------------------------------------------------- /integration/docker/jobs/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG base_image="nextbreakpoint/flinkctl:latest" 2 | FROM ubuntu:latest AS download 3 | ARG dummies_version="0.0.6" 4 | RUN apt update -y && apt install -y curl 5 | RUN curl https://github.com/nextbreakpoint/flink-dummies/releases/download/v${dummies_version}/com.nextbreakpoint.flink.dummies-${dummies_version}.jar -L -o /com.nextbreakpoint.flink.dummies.jar 6 | FROM ${base_image} 7 | COPY --from=download /com.nextbreakpoint.flink.dummies.jar / 8 | -------------------------------------------------------------------------------- /integration/helm/jobs/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /integration/helm/jobs/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | appVersion: "1.0" 3 | description: A Helm chart for integration tests 4 | name: jobs 5 | version: 1.0 6 | -------------------------------------------------------------------------------- /integration/helm/jobs/templates/NOTES.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextbreakpoint/flink-controller/72f4ca978d417c4bc30fa69cae6f4f3fa8e53543/integration/helm/jobs/templates/NOTES.txt -------------------------------------------------------------------------------- /integration/helm/jobs/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "jobs.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "jobs.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "jobs.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | -------------------------------------------------------------------------------- /integration/helm/jobs/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | name: integration 6 | 7 | s3BucketName: nextbreakpoint-integration 8 | s3Endpoint: http://minio-headless:9000 9 | s3PathStyleAccess: "true" 10 | s3AccessKey: minioaccesskey 11 | s3SecretKey: miniosecretkey 12 | 13 | flinkVersion: "1.20.0" 14 | -------------------------------------------------------------------------------- /integration/helm/minio/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | appVersion: "1.0" 3 | description: A Helm chart for installing Minio 4 | name: minio 5 | version: 0.1.0 6 | -------------------------------------------------------------------------------- /integration/helm/minio/templates/NOTES.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextbreakpoint/flink-controller/72f4ca978d417c4bc30fa69cae6f4f3fa8e53543/integration/helm/minio/templates/NOTES.txt -------------------------------------------------------------------------------- /integration/helm/minio/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "minio.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "minio.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "minio.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | -------------------------------------------------------------------------------- /integration/helm/minio/templates/service.yaml: -------------------------------------------------------------------------------- 1 | {{- $fullname := include "minio.fullname" . -}} 2 | {{- $name := include "minio.name" . -}} 3 | {{- $chart := include "minio.chart" . -}} 4 | {{- $root := . }} 5 | apiVersion: v1 6 | kind: Service 7 | metadata: 8 | name: {{ $fullname }}-headless 9 | labels: 10 | app: {{ $name }} 11 | chart: {{ $chart }} 12 | release: {{ $root.Release.Name }} 13 | heritage: {{ $root.Release.Service }} 14 | spec: 15 | clusterIP: None 16 | ports: 17 | - port: 9000 18 | targetPort: http 19 | protocol: TCP 20 | name: minio 21 | - port: 9001 22 | targetPort: http 23 | protocol: TCP 24 | name: minio-console 25 | selector: 26 | app: {{ $name }} 27 | release: {{ $root.Release.Name }} 28 | --- 29 | apiVersion: v1 30 | kind: Service 31 | metadata: 32 | name: {{ $fullname }} 33 | labels: 34 | app: {{ $name }} 35 | chart: {{ $chart }} 36 | release: {{ $root.Release.Name }} 37 | heritage: {{ $root.Release.Service }} 38 | external: "false" 39 | spec: 40 | type: ClusterIP 41 | ports: 42 | - port: 9000 43 | targetPort: http 44 | protocol: TCP 45 | name: minio 46 | - port: 9001 47 | targetPort: http 48 | protocol: TCP 49 | name: minio-console 50 | selector: 51 | app: {{ $name }} 52 | release: {{ $root.Release.Name }} 53 | -------------------------------------------------------------------------------- /integration/helm/minio/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for kafka. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | minio: 6 | accessKey: "minioaccesskey" 7 | secretKey: "miniosecretkey" 8 | -------------------------------------------------------------------------------- /integration/job-spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "jobParallelism": 1, 3 | "savepoint": { 4 | "savepointMode": "Manual", 5 | "savepointInterval": 0, 6 | "savepointTargetPath": "s3p://nextbreakpoint-integration/0/savepoints" 7 | }, 8 | "restart": { 9 | "restartPolicy": "Always", 10 | "restartDelay": 60, 11 | "restartTimeout": 120 12 | }, 13 | "bootstrap": { 14 | "serviceAccount": "flink-bootstrap", 15 | "pullPolicy": "Never", 16 | "image": "integration/jobs:latest", 17 | "jarPath": "com.nextbreakpoint.flink.dummies.jar", 18 | "className": "com.nextbreakpoint.flink.dummies.TemperatureMeasurementMain", 19 | "arguments": [ 20 | "--CONFIG_PATH", 21 | "file:///var/config/measurement.properties" 22 | ], 23 | "resources": { 24 | "limits": { 25 | "cpu": "0.5", 26 | "memory": "128Mi" 27 | }, 28 | "requests": { 29 | "cpu": "0.05", 30 | "memory": "128Mi" 31 | } 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /maven-version-rules.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | .*-alpha.* 8 | .*-beta.* 9 | .*-Beta.* 10 | .*-ea.* 11 | .*-RC.* 12 | .*-M.* 13 | .*CR1 14 | .*CR2 15 | 16 | -------------------------------------------------------------------------------- /pipeline/docker-build-images.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -x 4 | set -e 5 | 6 | eval "$(minikube docker-env)" 7 | 8 | docker build -t integration/flinkctl:1.5.0 . 9 | docker build -t integration/flink:1.20.0 integration/docker/flink --build-arg flink_version=1.20.0 --build-arg scala_version=2.12 10 | docker build -t integration/jobs:1.20.0 integration/docker/jobs --build-arg base_image=integration/flinkctl:1.5.0 --build-arg flink_version=1.20.0 --build-arg scala_version=2.12 --build-arg dummies_version=0.0.6 11 | -------------------------------------------------------------------------------- /pipeline/docker-login.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -e 4 | 5 | eval "$(minikube docker-env)" 6 | 7 | echo "$DOCKER_PASSWORD" | docker login --username="$DOCKER_USERNAME" --password-stdin 8 | -------------------------------------------------------------------------------- /pipeline/docker-push-image.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -x 4 | set -e 5 | 6 | eval "$(minikube docker-env)" 7 | 8 | docker tag integration/flinkctl:1.5.0 "nextbreakpoint/flinkctl:$DOCKER_IMAGE_TAG" 9 | docker push "nextbreakpoint/flinkctl:$DOCKER_IMAGE_TAG" 10 | -------------------------------------------------------------------------------- /pipeline/docker-update-latest.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -x 4 | set -e 5 | 6 | eval "$(minikube docker-env)" 7 | 8 | docker tag "integration/jobs:${FLINK_VERSION}" integration/jobs:latest 9 | docker tag "integration/flink:${FLINK_VERSION}" integration/flink:latest 10 | -------------------------------------------------------------------------------- /pipeline/install-docker.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -x 4 | set -e 5 | 6 | sudo apt-get update -y && sudo apt-get install -y apt-transport-https ca-certificates software-properties-common curl jq socat 7 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - 8 | sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable" 9 | sudo apt-get update -y && sudo apt-get install -y docker-ce 10 | sudo usermod -aG docker "$USER" && newgrp docker 11 | -------------------------------------------------------------------------------- /pipeline/install-helm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -x 4 | set -e 5 | 6 | curl https://get.helm.sh/helm-v3.0.2-linux-amd64.tar.gz -L -o /tmp/helm.tar.gz 7 | tar -xzf /tmp/helm.tar.gz 8 | sudo cp linux-amd64/helm /usr/local/bin 9 | rm -fR linux-amd64 helm.tar.gz 10 | -------------------------------------------------------------------------------- /pipeline/install-java.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -x 4 | set -e 5 | 6 | sudo apt-get install -y openjdk-21-jdk -------------------------------------------------------------------------------- /pipeline/install-kubectl.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -x 4 | set -e 5 | 6 | curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - 7 | sudo add-apt-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main" 8 | sudo apt update -y && sudo apt -y install kubectl 9 | -------------------------------------------------------------------------------- /pipeline/install-minikube.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -x 4 | set -e 5 | 6 | curl https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 -L -o /tmp/minikube-linux-amd64 7 | chmod +x /tmp/minikube-linux-amd64 8 | sudo mv /tmp/minikube-linux-amd64 /usr/local/bin/minikube 9 | 10 | -------------------------------------------------------------------------------- /pipeline/print-dependencies.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -x 4 | set -e 5 | 6 | mvn dependency:tree 7 | -------------------------------------------------------------------------------- /pipeline/print-java-version.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -x 4 | set -e 5 | 6 | "$JAVA_HOME/bin/java" -version 7 | -------------------------------------------------------------------------------- /pipeline/run-integration-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -x 4 | set -e 5 | 6 | OPERATOR_HOST="$(minikube ip)" 7 | 8 | export OPERATOR_HOST 9 | 10 | mvn -t toolchains-pipeline.xml verify -Dtest=com.nextbreakpoint.flink.controller.integration.EnsureBehaviourIT 11 | 12 | -------------------------------------------------------------------------------- /pipeline/run-integration-tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -x 4 | set -e 5 | 6 | OPERATOR_HOST="$(minikube ip)" 7 | 8 | export OPERATOR_HOST 9 | 10 | mvn -t toolchains-pipeline.xml verify 11 | 12 | -------------------------------------------------------------------------------- /pipeline/run-minikube.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -x 4 | set -e 5 | 6 | minikube start --cpus=2 --memory=6gb --vm-driver=docker --kubernetes-version v1.31.0 7 | #chown -R $USER $HOME/.kube $HOME/.minikube 8 | #chgrp -R $USER $HOME/.kube $HOME/.minikube 9 | 10 | -------------------------------------------------------------------------------- /pipeline/run-tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -x 4 | set -e 5 | 6 | mvn -t toolchains-pipeline.xml test 7 | 8 | -------------------------------------------------------------------------------- /scripts/registry/README.md: -------------------------------------------------------------------------------- 1 | # Install a local Docker Registry 2 | 3 | Create docker-registry files: 4 | 5 | ./docker-registry-setup.sh 6 | 7 | Create docker-registry: 8 | 9 | kubectl create -f docker-registry.yaml 10 | 11 | Add this entry to your hosts file (etc/hosts): 12 | 13 | 127.0.0.1 registry 14 | 15 | Create pull secrets in flink namespace: 16 | 17 | kubectl create secret docker-registry regcred -n flink --docker-server=registry:30000 --docker-username=test --docker-password=password --docker-email= 18 | 19 | Associate pull secrets to flink-operator service account: 20 | 21 | kubectl patch serviceaccount flink-operator -n flink -p '{"imagePullSecrets": [{"name": "regcred"}]}' 22 | 23 | You can tag and push images to your local registry: 24 | 25 | docker tag flink:1.9.2 registry:30000/flink:1.9.2 26 | docker login registry:30000 27 | docker push registry:30000/flink:1.9.2 28 | -------------------------------------------------------------------------------- /scripts/registry/docker-registry-ssl.conf: -------------------------------------------------------------------------------- 1 | [req] 2 | distinguished_name = distinguished_name_req 3 | [distinguished_name_req] 4 | [v3_ca] 5 | subjectAltName = IP:127.0.0.1 6 | -------------------------------------------------------------------------------- /scripts/run-bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | minikubeIp() { 4 | minikube ip 5 | } 6 | 7 | kubeConfig() { 8 | echo ~/.kube/config 9 | } 10 | 11 | java --module-path com.nextbreakpoint.flink.control-1.5.0-shaded.jar --module com.nextbreakpoint.flink.control/com.nextbreakpoint.flink.controller.cli.Main \ 12 | bootstrap run --namespace=flink-jobs --flink-hostname="$(minikubeIp)" --kube-config="$(kubeConfig)" --cluster-name=cluster-1 --job-name=job-1 \ 13 | --jar-path=com.nextbreakpoint.flink.dummies.jar --class-name=com.nextbreakpoint.flink.dummies.TemperatureMeasurementMain --parallelism=1 14 | -------------------------------------------------------------------------------- /scripts/run-operator.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | minikubeIp() { 4 | minikube ip 5 | } 6 | 7 | kubeConfig() { 8 | echo ~/.kube/config 9 | } 10 | 11 | java --module-path com.nextbreakpoint.flink.control-1.5.0-shaded.jar --module com.nextbreakpoint.flink.control/com.nextbreakpoint.flink.controller.cli.Main \ 12 | operator run --dry-run --namespace=flink --port=4444 --flink-hostname="$(minikubeIp)" --kube-config="$(kubeConfig)" \ 13 | --keystore-path=secrets/keystore-operator-api.jks --truststore-path=secrets/truststore-operator-api.jks \ 14 | --keystore-secret=keystore-password --truststore-secret=truststore-password 15 | 16 | -------------------------------------------------------------------------------- /scripts/run-supervisor.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | minikubeIp() { 4 | minikube ip 5 | } 6 | 7 | kubeConfig() { 8 | echo ~/.kube/config 9 | } 10 | 11 | java --module-path com.nextbreakpoint.flink.control-1.5.0-shaded.jar --module com.nextbreakpoint.flink.control/com.nextbreakpoint.flink.controller.cli.Main \ 12 | supervisor run --dry-run --namespace=flink --flink-hostname="$(minikubeIp)" --kube-config="$(kubeConfig)" --cluster-name=cluster-1 13 | -------------------------------------------------------------------------------- /src/main/java/com/nextbreakpoint/flink/controller/k8s/factory/BootstrapResourcesFactory.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.factory; 2 | 3 | import com.nextbreakpoint.flink.controller.k8s.crd.V1BootstrapSpec; 4 | import io.kubernetes.client.openapi.models.V1Job; 5 | 6 | public interface BootstrapResourcesFactory { 7 | V1Job createBootstrapJob( 8 | String namespace, 9 | String owner, 10 | String clusterName, 11 | String jobName, 12 | V1BootstrapSpec bootstrapSpec, 13 | String savepointPath, 14 | Integer parallelism, 15 | Boolean dryRun 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/nextbreakpoint/flink/controller/k8s/factory/ClusterResourcesFactory.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.factory; 2 | 3 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkClusterSpec; 4 | import io.kubernetes.client.openapi.models.V1Pod; 5 | import io.kubernetes.client.openapi.models.V1Service; 6 | 7 | public interface ClusterResourcesFactory { 8 | V1Service createService( 9 | String namespace, 10 | String owner, 11 | String clusterName, 12 | V1FlinkClusterSpec clusterSpec 13 | ); 14 | 15 | V1Pod createJobManagerPod( 16 | String namespace, 17 | String owner, 18 | String clusterName, 19 | V1FlinkClusterSpec clusterSpec 20 | ); 21 | 22 | V1Pod createTaskManagerPod( 23 | String namespace, 24 | String owner, 25 | String clusterName, 26 | V1FlinkClusterSpec clusterSpec 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/nextbreakpoint/flink/controller/k8s/factory/DeploymentResourcesFactory.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.factory; 2 | 3 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkCluster; 4 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkClusterSpec; 5 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkDeployment; 6 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkDeploymentSpec; 7 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkJob; 8 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkJobSpec; 9 | 10 | public interface DeploymentResourcesFactory { 11 | V1FlinkDeployment createFlinkDeployment( 12 | String namespace, 13 | String owner, 14 | String clusterName, 15 | V1FlinkDeploymentSpec deploymentSpec 16 | ); 17 | 18 | V1FlinkCluster createFlinkCluster( 19 | String namespace, 20 | String owner, 21 | String clusterName, 22 | V1FlinkClusterSpec clusterSpec 23 | ); 24 | 25 | V1FlinkJob createFlinkJob( 26 | String namespace, 27 | String owner, 28 | String clusterName, 29 | String jobName, 30 | V1FlinkJobSpec jobSpec 31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/nextbreakpoint/flink/controller/k8s/factory/SupervisorResourcesFactory.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.factory; 2 | 3 | import com.nextbreakpoint.flink.controller.k8s.crd.V1SupervisorSpec; 4 | import io.kubernetes.client.openapi.models.V1Deployment; 5 | 6 | public interface SupervisorResourcesFactory { 7 | V1Deployment createSupervisorDeployment( 8 | String namespace, 9 | String owner, 10 | String clusterName, 11 | V1SupervisorSpec supervisorSpec, 12 | Boolean dryRun 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/ClusterCreate.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.ClusterCommand 4 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | 9 | class ClusterCreate(private val factory: WebClientFactory = WebClientDefaultFactory) : ClusterCommand { 10 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, args: String) { 11 | HttpUtils.postJson(factory, connectionConfig, "/api/v1/clusters/$clusterName", args) 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/ClusterDelete.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.ClusterCommand 4 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | 9 | class ClusterDelete(private val factory: WebClientFactory = WebClientDefaultFactory) : ClusterCommand { 10 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, unused: Void?) { 11 | HttpUtils.delete(factory, connectionConfig, "/api/v1/clusters/$clusterName") 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/ClusterScale.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.ClusterCommand 4 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | import com.nextbreakpoint.flink.controller.common.ScaleClusterOptions 9 | 10 | class ClusterScale(private val factory: WebClientFactory = WebClientDefaultFactory) : ClusterCommand { 11 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, args: ScaleClusterOptions) { 12 | HttpUtils.putJson(factory, connectionConfig, "/api/v1/clusters/$clusterName/scale", args) 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/ClusterStart.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.ClusterCommand 4 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | import com.nextbreakpoint.flink.controller.common.StartOptions 9 | 10 | class ClusterStart(private val factory: WebClientFactory = WebClientDefaultFactory) : ClusterCommand { 11 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, args: StartOptions) { 12 | HttpUtils.putJson(factory, connectionConfig, "/api/v1/clusters/$clusterName/start", args) 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/ClusterStatus.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.ClusterCommand 4 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | 9 | class ClusterStatus(private val factory: WebClientFactory = WebClientDefaultFactory) : ClusterCommand { 10 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, unused: Void?) { 11 | HttpUtils.get(factory, connectionConfig, "/api/v1/clusters/$clusterName/status") 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/ClusterStop.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.ClusterCommand 4 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | import com.nextbreakpoint.flink.controller.common.StopOptions 9 | 10 | class ClusterStop(private val factory: WebClientFactory = WebClientDefaultFactory) : ClusterCommand { 11 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, args: StopOptions) { 12 | HttpUtils.putJson(factory, connectionConfig, "/api/v1/clusters/$clusterName/stop", args) 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/ClusterUpdate.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.ClusterCommand 4 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | 9 | class ClusterUpdate(private val factory: WebClientFactory = WebClientDefaultFactory) : ClusterCommand { 10 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, args: String) { 11 | HttpUtils.putJson(factory, connectionConfig, "/api/v1/clusters/$clusterName", args) 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/ClustersList.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 4 | import com.nextbreakpoint.flink.controller.cli.core.OperatorCommand 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | 9 | class ClustersList(private val factory: WebClientFactory = WebClientDefaultFactory) : OperatorCommand { 10 | override fun run(connectionConfig: ConnectionConfig) { 11 | HttpUtils.get(factory, connectionConfig, "/api/v1/clusters") 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/DeploymentCreate.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.DeploymentCommand 4 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | 9 | class DeploymentCreate(private val factory: WebClientFactory = WebClientDefaultFactory) : DeploymentCommand { 10 | override fun run(connectionConfig: ConnectionConfig, deploymentName: String, args: String) { 11 | HttpUtils.postJson(factory, connectionConfig, "/api/v1/deployments/$deploymentName", args) 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/DeploymentDelete.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.DeploymentCommand 4 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | 9 | class DeploymentDelete(private val factory: WebClientFactory = WebClientDefaultFactory) : DeploymentCommand { 10 | override fun run(connectionConfig: ConnectionConfig, deploymentName: String, unused: Void?) { 11 | HttpUtils.delete(factory, connectionConfig, "/api/v1/deployments/$deploymentName") 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/DeploymentStatus.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.DeploymentCommand 4 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | 9 | class DeploymentStatus(private val factory: WebClientFactory = WebClientDefaultFactory) : DeploymentCommand { 10 | override fun run(connectionConfig: ConnectionConfig, deploymentName: String, unused: Void?) { 11 | HttpUtils.get(factory, connectionConfig, "/api/v1/deployments/$deploymentName/status") 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/DeploymentUpdate.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.DeploymentCommand 4 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | 9 | class DeploymentUpdate(private val factory: WebClientFactory = WebClientDefaultFactory) : DeploymentCommand { 10 | override fun run(connectionConfig: ConnectionConfig, deploymentName: String, args: String) { 11 | HttpUtils.putJson(factory, connectionConfig, "/api/v1/deployments/$deploymentName", args) 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/DeploymentsList.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 4 | import com.nextbreakpoint.flink.controller.cli.core.OperatorCommand 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | 9 | class DeploymentsList(private val factory: WebClientFactory = WebClientDefaultFactory) : OperatorCommand { 10 | override fun run(connectionConfig: ConnectionConfig) { 11 | HttpUtils.get(factory, connectionConfig, "/api/v1/deployments") 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/JobCreate.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 4 | import com.nextbreakpoint.flink.controller.cli.core.JobCommand 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | 9 | class JobCreate(private val factory: WebClientFactory = WebClientDefaultFactory) : JobCommand { 10 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, jobName: String, args: String) { 11 | HttpUtils.postJson(factory, connectionConfig, "/api/v1/clusters/$clusterName/jobs/$jobName", args) 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/JobDelete.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 4 | import com.nextbreakpoint.flink.controller.cli.core.JobCommand 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | 9 | class JobDelete(private val factory: WebClientFactory = WebClientDefaultFactory) : JobCommand { 10 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, jobName: String, unused: Void?) { 11 | HttpUtils.delete(factory, connectionConfig, "/api/v1/clusters/$clusterName/jobs/$jobName") 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/JobDetails.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 4 | import com.nextbreakpoint.flink.controller.cli.core.JobCommand 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | 9 | class JobDetails(private val factory: WebClientFactory = WebClientDefaultFactory) : JobCommand { 10 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, jobName: String, unused: Void?) { 11 | HttpUtils.get(factory, connectionConfig, "/api/v1/clusters/$clusterName/jobs/$jobName/details") 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/JobManagerMetrics.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.ClusterCommand 4 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | 9 | class JobManagerMetrics(private val factory: WebClientFactory = WebClientDefaultFactory) : ClusterCommand { 10 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, unused: Void?) { 11 | HttpUtils.get(factory, connectionConfig, "/api/v1/clusters/$clusterName/jobmanager/metrics") 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/JobMetrics.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 4 | import com.nextbreakpoint.flink.controller.cli.core.JobCommand 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | 9 | class JobMetrics(private val factory: WebClientFactory = WebClientDefaultFactory) : JobCommand { 10 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, jobName: String, unused: Void?) { 11 | HttpUtils.get(factory, connectionConfig, "/api/v1/clusters/$clusterName/jobs/$jobName/metrics") 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/JobScale.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 4 | import com.nextbreakpoint.flink.controller.cli.core.JobCommand 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | import com.nextbreakpoint.flink.controller.common.ScaleJobOptions 9 | 10 | class JobScale(private val factory: WebClientFactory = WebClientDefaultFactory) : JobCommand { 11 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, jobName: String, args: ScaleJobOptions) { 12 | HttpUtils.putJson(factory, connectionConfig, "/api/v1/clusters/$clusterName/jobs/$jobName/scale", args) 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/JobStart.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 4 | import com.nextbreakpoint.flink.controller.cli.core.JobCommand 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | import com.nextbreakpoint.flink.controller.common.StartOptions 9 | 10 | class JobStart(private val factory: WebClientFactory = WebClientDefaultFactory) : JobCommand { 11 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, jobName: String, args: StartOptions) { 12 | HttpUtils.putJson(factory, connectionConfig, "/api/v1/clusters/$clusterName/jobs/$jobName/start", args) 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/JobStatus.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 4 | import com.nextbreakpoint.flink.controller.cli.core.JobCommand 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | 9 | class JobStatus(private val factory: WebClientFactory = WebClientDefaultFactory) : JobCommand { 10 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, jobName: String, unused: Void?) { 11 | HttpUtils.get(factory, connectionConfig, "/api/v1/clusters/$clusterName/jobs/$jobName/status") 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/JobStop.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 4 | import com.nextbreakpoint.flink.controller.cli.core.JobCommand 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | import com.nextbreakpoint.flink.controller.common.StopOptions 9 | 10 | class JobStop(private val factory: WebClientFactory = WebClientDefaultFactory) : JobCommand { 11 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, jobName: String, args: StopOptions) { 12 | HttpUtils.putJson(factory, connectionConfig, "/api/v1/clusters/$clusterName/jobs/$jobName/stop", args) 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/JobUpdate.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 4 | import com.nextbreakpoint.flink.controller.cli.core.JobCommand 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | 9 | class JobUpdate(private val factory: WebClientFactory = WebClientDefaultFactory) : JobCommand { 10 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, jobName: String, args: String) { 11 | HttpUtils.putJson(factory, connectionConfig, "/api/v1/clusters/$clusterName/jobs/$jobName", args) 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/JobsList.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.ClusterCommand 4 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | 9 | class JobsList(private val factory: WebClientFactory = WebClientDefaultFactory) : ClusterCommand { 10 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, unused: Void?) { 11 | HttpUtils.get(factory, connectionConfig, "/api/v1/clusters/$clusterName/jobs") 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/LaunchBootstrap.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.LaunchCommand 4 | import com.nextbreakpoint.flink.controller.common.BootstrapOptions 5 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 6 | import com.nextbreakpoint.flink.controller.k8s.bootstrap.BootstrapRunner 7 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 8 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 9 | import com.nextbreakpoint.flink.controller.k8s.controller.Controller 10 | 11 | class LaunchBootstrap : LaunchCommand { 12 | companion object { 13 | private val kubeClient = KubeClient 14 | private val flinkClient = FlinkClient 15 | } 16 | 17 | override fun run(flinkOptions: FlinkOptions, namespace: String, options: BootstrapOptions) { 18 | val controller = Controller(flinkOptions, flinkClient, kubeClient, options.dryRun) 19 | 20 | val runner = BootstrapRunner(controller, namespace, options) 21 | 22 | runner.run() 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/SavepointForget.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 4 | import com.nextbreakpoint.flink.controller.cli.core.JobCommand 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | 9 | class SavepointForget(private val factory: WebClientFactory = WebClientDefaultFactory) : JobCommand { 10 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, jobName: String, unused: Void?) { 11 | HttpUtils.delete(factory, connectionConfig, "/api/v1/clusters/$clusterName/jobs/$jobName/savepoint") 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/SavepointTrigger.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 4 | import com.nextbreakpoint.flink.controller.cli.core.JobCommand 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | 9 | class SavepointTrigger(private val factory: WebClientFactory = WebClientDefaultFactory) : JobCommand { 10 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, jobName: String, unused: Void?) { 11 | HttpUtils.putJson(factory, connectionConfig, "/api/v1/clusters/$clusterName/jobs/$jobName/savepoint", null) 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/TaskManagerDetails.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.ClusterCommand 4 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | import com.nextbreakpoint.flink.controller.common.TaskManagerId 9 | 10 | class TaskManagerDetails(private val factory: WebClientFactory = WebClientDefaultFactory) : ClusterCommand { 11 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, args: TaskManagerId) { 12 | HttpUtils.get(factory, connectionConfig, "/api/v1/clusters/$clusterName/taskmanagers/${args.taskmanagerId}/details") 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/TaskManagerMetrics.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.ClusterCommand 4 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | import com.nextbreakpoint.flink.controller.common.TaskManagerId 9 | 10 | class TaskManagerMetrics(private val factory: WebClientFactory = WebClientDefaultFactory) : ClusterCommand { 11 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, args: TaskManagerId) { 12 | HttpUtils.get(factory, connectionConfig, "/api/v1/clusters/$clusterName/taskmanagers/${args.taskmanagerId}/metrics") 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/command/TaskManagersList.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.command 2 | 3 | import com.nextbreakpoint.flink.controller.cli.core.ClusterCommand 4 | import com.nextbreakpoint.flink.controller.cli.core.HttpUtils 5 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientDefaultFactory 6 | import com.nextbreakpoint.flink.controller.cli.factory.WebClientFactory 7 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 8 | 9 | class TaskManagersList(private val factory: WebClientFactory = WebClientDefaultFactory) : ClusterCommand { 10 | override fun run(connectionConfig: ConnectionConfig, clusterName: String, unused: Void?) { 11 | HttpUtils.get(factory, connectionConfig, "/api/v1/clusters/$clusterName/taskmanagers") 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/core/ClusterCommand.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.core 2 | 3 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 4 | 5 | interface ClusterCommand { 6 | fun run(connectionConfig: ConnectionConfig, clusterName: String, args: T) 7 | } 8 | 9 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/core/DeploymentCommand.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.core 2 | 3 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 4 | 5 | interface DeploymentCommand { 6 | fun run(connectionConfig: ConnectionConfig, deploymentName: String, args: T) 7 | } 8 | 9 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/core/JobCommand.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.core 2 | 3 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 4 | 5 | interface JobCommand { 6 | fun run(connectionConfig: ConnectionConfig, clusterName: String, jobName: String, args: T) 7 | } 8 | 9 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/core/LaunchCommand.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.core 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | 5 | interface LaunchCommand { 6 | fun run(flinkOptions: FlinkOptions, namespace: String, args: T) 7 | } 8 | 9 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/core/OperatorCommand.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.core 2 | 3 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 4 | 5 | interface OperatorCommand { 6 | fun run(connectionConfig: ConnectionConfig) 7 | } 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/cli/factory/WebClientFactory.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.cli.factory 2 | 3 | import com.nextbreakpoint.flink.controller.common.ConnectionConfig 4 | import io.vertx.rxjava.ext.web.client.WebClient 5 | 6 | interface WebClientFactory { 7 | fun create(connectionConfig: ConnectionConfig): WebClient 8 | } 9 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/Action.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | enum class Action { 4 | START, STOP, TRIGGER_SAVEPOINT, FORGET_SAVEPOINT, NONE 5 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/BootstrapOptions.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | data class BootstrapOptions( 4 | val clusterName: String, 5 | val jobName: String, 6 | val jarPath: String, 7 | val className: String, 8 | val parallelism: Int, 9 | val savepointPath: String?, 10 | val arguments: List, 11 | val dryRun: Boolean 12 | ) -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/ClusterSelector.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | data class ClusterSelector( 4 | val namespace: String, 5 | val clusterName: String 6 | ) { 7 | override fun toString(): String { 8 | return "$namespace:$clusterName" 9 | } 10 | 11 | fun resourceName() = clusterName 12 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/ClusterStatus.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | enum class ClusterStatus { 4 | Unknown, 5 | Starting, 6 | Started, 7 | Stopping, 8 | Stopped, 9 | Terminated 10 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/ConnectionConfig.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | data class ConnectionConfig( 4 | val host: String, 5 | val port: Int, 6 | val keystorePath: String?, 7 | val keystoreSecret: String?, 8 | val truststorePath: String?, 9 | val truststoreSecret: String? 10 | ) -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/DeleteOptions.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | data class DeleteOptions( 4 | val label: String, 5 | val value: String, 6 | val limit: Int 7 | ) -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/DeploymentSelector.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | data class DeploymentSelector( 4 | val namespace: String, 5 | val deploymentName: String 6 | ) { 7 | override fun toString(): String { 8 | return "$namespace:$deploymentName" 9 | } 10 | 11 | fun resourceName() = deploymentName 12 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/FlinkAddress.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | data class FlinkAddress(val host: String, val port: Int, val protocol: String? = "http") -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/FlinkOptions.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | data class FlinkOptions( 4 | val hostname: String?, 5 | val portForward: Int?, 6 | val useNodePort: Boolean 7 | ) -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/JobManagerStats.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | class JobManagerStats( 4 | val jvmCPUTime: Long, 5 | val jvmCPULoad: Double, 6 | val jvmThreadsCount: Int, 7 | val jvmMemoryHeapMax: Long, 8 | val jvmMemoryHeapUsed: Long, 9 | val jvmMemoryHeapCommitted: Long, 10 | val jvmMemoryNonHeapMax: Long, 11 | val jvmMemoryNonHeapUsed: Long, 12 | val jvmMemoryNonHeapCommitted: Long, 13 | val jvmMemoryDirectCount: Int, 14 | val jvmMemoryDirectMemoryUsed: Long, 15 | val jvmMemoryDirectTotalCapacity: Long, 16 | val jvmMemoryMappedCount: Int, 17 | val jvmMemoryMappedMemoryUsed: Long, 18 | val jvmMemoryMappedTotalCapacity: Long, 19 | val jvmGarbageCollectorCopyTime: Long, 20 | val jvmGarbageCollectorCopyCount: Int, 21 | val jvmGarbageCollectorMarkSweepCompactTime: Long, 22 | val jvmGarbageCollectorMarkSweepCompactCount: Int, 23 | val jvmClassLoaderClassesLoaded: Int, 24 | val jvmClassLoaderClassesUnloaded: Int, 25 | val taskSlotsTotal: Int, 26 | val taskSlotsAvailable: Int, 27 | val numRegisteredTaskManagers: Int, 28 | val numRunningJobs: Int 29 | ) 30 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/JobSelector.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | data class JobSelector( 4 | val namespace: String, 5 | val clusterName: String, 6 | val jobName: String 7 | ) { 8 | override fun toString(): String { 9 | return "$namespace:$clusterName:$jobName" 10 | } 11 | 12 | fun resourceName() = "$clusterName-$jobName" 13 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/JobStats.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | class JobStats( 4 | val totalNumberOfCheckpoints: Int, 5 | val numberOfCompletedCheckpoints: Int, 6 | val numberOfInProgressCheckpoints: Int, 7 | val numberOfFailedCheckpoints: Int, 8 | val lastCheckpointDuration: Long, 9 | val lastCheckpointSize: Long, 10 | val lastCheckpointRestoreTimestamp: Long, 11 | val lastCheckpointAlignmentBuffered: Long, 12 | val lastCheckpointExternalPath: String, 13 | val fullRestarts: Int, 14 | val restartingTime: Long, 15 | val uptime: Long, 16 | val downtime: Long 17 | ) 18 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/JobStatus.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | enum class JobStatus { 4 | Unknown, 5 | Starting, 6 | Started, 7 | Stopping, 8 | Stopped, 9 | Terminated 10 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/OperatorOptions.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | data class OperatorOptions( 4 | val port: Int, 5 | val keystorePath: String?, 6 | val keystoreSecret: String?, 7 | val truststorePath: String?, 8 | val truststoreSecret: String?, 9 | val pollingInterval: Long, 10 | val taskTimeout: Long, 11 | val dryRun: Boolean 12 | ) -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/RescalePolicy.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | enum class RescalePolicy { 4 | None, 5 | JobParallelism 6 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/RescaleStatus.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | data class RescaleStatus(val status: String) 4 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/ResourceStatus.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | enum class ResourceStatus { 4 | Updating, 5 | Updated, 6 | Unknown 7 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/RestartPolicy.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | enum class RestartPolicy { 4 | Never, 5 | Always, 6 | OnlyIfFailed 7 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/RunJarOptions.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | data class RunJarOptions( 4 | val jarFileId: String, 5 | val className: String, 6 | val parallelism: Int, 7 | val savepointPath: String?, 8 | val arguments: List 9 | ) -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/RunnerOptions.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | data class RunnerOptions( 4 | val pollingInterval: Long, 5 | val taskTimeout: Long, 6 | val serverConfig: ServerConfig 7 | ) -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/SavepointMode.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | enum class SavepointMode { 4 | Manual, 5 | Automatic 6 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/SavepointOptions.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | import com.fasterxml.jackson.annotation.JsonAutoDetect 4 | 5 | @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) 6 | data class SavepointOptions( 7 | val targetPath: String? 8 | ) -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/SavepointRequest.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | data class SavepointRequest( 4 | val jobId: String, 5 | val triggerId: String 6 | ) 7 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/SavepointStatus.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | data class SavepointStatus(val status: String, val location: String?) 4 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/ScaleClusterOptions.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | import com.fasterxml.jackson.annotation.JsonAutoDetect 4 | 5 | @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) 6 | data class ScaleClusterOptions( 7 | val taskManagers: Int 8 | ) -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/ScaleJobOptions.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | import com.fasterxml.jackson.annotation.JsonAutoDetect 4 | 5 | @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) 6 | data class ScaleJobOptions( 7 | val parallelism: Int 8 | ) -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/ServerConfig.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | data class ServerConfig( 4 | val port: Int, 5 | val keystorePath: String?, 6 | val keystoreSecret: String?, 7 | val truststorePath: String?, 8 | val truststoreSecret: String? 9 | ) -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/StartOptions.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | import com.fasterxml.jackson.annotation.JsonAutoDetect 4 | 5 | @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) 6 | data class StartOptions( 7 | val withoutSavepoint: Boolean 8 | ) -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/StopOptions.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | import com.fasterxml.jackson.annotation.JsonAutoDetect 4 | 5 | @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) 6 | data class StopOptions( 7 | val withoutSavepoint: Boolean 8 | ) -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/SupervisorOptions.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | data class SupervisorOptions( 4 | val port: Int, 5 | val keystorePath: String?, 6 | val keystoreSecret: String?, 7 | val truststorePath: String?, 8 | val truststoreSecret: String?, 9 | val clusterName: String, 10 | val pollingInterval: Long, 11 | val taskTimeout: Long, 12 | val dryRun: Boolean 13 | ) -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/TaskManagerId.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | data class TaskManagerId( 4 | val taskmanagerId: String 5 | ) -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/common/TaskManagerStats.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.common 2 | 3 | class TaskManagerStats( 4 | val jvmCPUTime: Long, 5 | val jvmCPULoad: Double, 6 | val jvmThreadsCount: Int, 7 | val jvmMemoryHeapMax: Long, 8 | val jvmMemoryHeapUsed: Long, 9 | val jvmMemoryHeapCommitted: Long, 10 | val jvmMemoryNonHeapMax: Long, 11 | val jvmMemoryNonHeapUsed: Long, 12 | val jvmMemoryNonHeapCommitted: Long, 13 | val jvmMemoryDirectCount: Int, 14 | val jvmMemoryDirectMemoryUsed: Long, 15 | val jvmMemoryDirectTotalCapacity: Long, 16 | val jvmMemoryMappedCount: Int, 17 | val jvmMemoryMappedMemoryUsed: Long, 18 | val jvmMemoryMappedTotalCapacity: Long, 19 | val jvmGarbageCollectorCopyTime: Long, 20 | val jvmGarbageCollectorCopyCount: Int, 21 | val jvmGarbageCollectorMarkSweepCompactTime: Long, 22 | val jvmGarbageCollectorMarkSweepCompactCount: Int, 23 | val jvmClassLoaderClassesLoaded: Int, 24 | val jvmClassLoaderClassesUnloaded: Int, 25 | val taskSlotsTotal: Int, 26 | val taskSlotsAvailable: Int, 27 | val numRegisteredTaskManagers: Int, 28 | val numRunningJobs: Int 29 | ) 30 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/bootstrap/BootstrapRunner.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.bootstrap 2 | 3 | import com.nextbreakpoint.flink.controller.common.BootstrapOptions 4 | import com.nextbreakpoint.flink.controller.k8s.controller.Controller 5 | 6 | class BootstrapRunner( 7 | private val controller: Controller, 8 | private val namespace: String, 9 | private val options: BootstrapOptions 10 | ) { 11 | fun run() { 12 | val bootstrap = Bootstrap(controller, namespace, options) 13 | 14 | if (!options.dryRun) { 15 | bootstrap.run() 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/common/FlinkClientException.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.common 2 | 3 | class FlinkClientException(message: String, cause: Exception? = null): RuntimeException(message, cause) 4 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/common/FlinkClusterConfiguration.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.common 2 | 3 | import com.nextbreakpoint.flink.controller.common.RescalePolicy 4 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkCluster 5 | 6 | object FlinkClusterConfiguration { 7 | fun getRescaleDelay(flinkCluster: V1FlinkCluster) : Long = 8 | flinkCluster.spec?.supervisor?.rescaleDelay?.toLong() ?: 60 9 | 10 | fun getRescalePolicy(flinkCluster: V1FlinkCluster) : RescalePolicy { 11 | val rescalePolicy = flinkCluster.spec?.supervisor?.rescalePolicy 12 | return if (rescalePolicy.isNullOrBlank()) RescalePolicy.JobParallelism else RescalePolicy.valueOf(rescalePolicy) 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/common/FlinkJobConfiguration.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.common 2 | 3 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkJob 4 | 5 | object FlinkJobConfiguration { 6 | fun getSavepointMode(flinkJob: V1FlinkJob) : String = 7 | flinkJob.spec?.savepoint?.savepointMode ?: "MANUAL" 8 | 9 | fun getSavepointPath(flinkJob: V1FlinkJob) : String? = 10 | flinkJob.spec?.savepoint?.savepointPath?.trim('\"') 11 | 12 | fun getSavepointInterval(flinkJob: V1FlinkJob) : Long = 13 | flinkJob.spec?.savepoint?.savepointInterval?.toLong() ?: 3600 14 | 15 | fun getSavepointTargetPath(flinkJob: V1FlinkJob) : String? = 16 | flinkJob.spec?.savepoint?.savepointTargetPath?.trim() 17 | 18 | fun getRestartPolicy(flinkJob: V1FlinkJob) : String = 19 | flinkJob.spec?.restart?.restartPolicy ?: "NEVER" 20 | 21 | fun getRestartDelay(flinkJob: V1FlinkJob) : Long = 22 | flinkJob.spec?.restart?.restartDelay?.toLong() ?: 60 23 | 24 | fun getRestartTimeout(flinkJob: V1FlinkJob) : Long = 25 | flinkJob.spec?.restart?.restartTimeout?.toLong() ?: 180 26 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/common/NotFoundException.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.common 2 | 3 | class NotFoundException(message: String): RuntimeException(message) -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/common/Task.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.common 2 | 3 | abstract class Task { 4 | abstract fun execute(target: T) 5 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/common/Time.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.common 2 | 3 | import java.time.Instant 4 | import java.time.OffsetDateTime 5 | import java.time.ZoneId 6 | 7 | object Time { 8 | fun toDateTime(timestamp: Long) = OffsetDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.of("UTC")) 9 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/common/Timeout.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.common 2 | 3 | object Timeout { 4 | val TASK_TIMEOUT = System.getenv("TASK_TIMEOUT")?.toLong() ?: 60L 5 | } 6 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/action/BatchJobCreate.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.action 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 5 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 6 | import com.nextbreakpoint.flink.controller.k8s.controller.core.JobAction 7 | import com.nextbreakpoint.flink.controller.k8s.controller.core.Result 8 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ResultStatus 9 | import io.kubernetes.client.openapi.models.V1Job 10 | import java.util.logging.Level 11 | import java.util.logging.Logger 12 | 13 | class BatchJobCreate(flinkOptions: FlinkOptions, flinkClient: FlinkClient, kubeClient: KubeClient) : JobAction(flinkOptions, flinkClient, kubeClient) { 14 | companion object { 15 | private val logger = Logger.getLogger(BatchJobCreate::class.simpleName) 16 | } 17 | 18 | override fun execute(namespace: String, clusterName: String, jobName: String, params: V1Job): Result { 19 | return try { 20 | val jobOut = kubeClient.createJob(namespace, params) 21 | 22 | Result( 23 | ResultStatus.OK, 24 | jobOut.metadata?.name ?: throw RuntimeException("Unexpected metadata") 25 | ) 26 | } catch (e : Exception) { 27 | logger.log(Level.SEVERE, "Can't create batch job", e) 28 | 29 | Result( 30 | ResultStatus.ERROR, 31 | null 32 | ) 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/action/BatchJobDelete.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.action 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 5 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 6 | import com.nextbreakpoint.flink.controller.k8s.controller.core.JobAction 7 | import com.nextbreakpoint.flink.controller.k8s.controller.core.Result 8 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ResultStatus 9 | import java.util.logging.Level 10 | import java.util.logging.Logger 11 | 12 | class BatchJobDelete(flinkOptions: FlinkOptions, flinkClient: FlinkClient, kubeClient: KubeClient) : JobAction(flinkOptions, flinkClient, kubeClient) { 13 | companion object { 14 | private val logger = Logger.getLogger(BatchJobDelete::class.simpleName) 15 | } 16 | 17 | override fun execute(namespace: String, clusterName: String, jobName: String, params: String): Result { 18 | return try { 19 | kubeClient.deleteJob(namespace, params) 20 | 21 | // kubeClient.deleteBootstrapPod(namespace, params) 22 | 23 | Result( 24 | ResultStatus.OK, 25 | null 26 | ) 27 | } catch (e : Exception) { 28 | logger.log(Level.SEVERE, "Can't delete batch job", e) 29 | 30 | Result( 31 | ResultStatus.ERROR, 32 | null 33 | ) 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/action/ClusterIsReady.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.action 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 5 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 6 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ClusterAction 7 | import com.nextbreakpoint.flink.controller.k8s.controller.core.Result 8 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ResultStatus 9 | import java.util.logging.Level 10 | import java.util.logging.Logger 11 | 12 | class ClusterIsReady(flinkOptions: FlinkOptions, flinkClient: FlinkClient, kubeClient: KubeClient) : ClusterAction(flinkOptions, flinkClient, kubeClient) { 13 | companion object { 14 | private val logger = Logger.getLogger(ClusterIsReady::class.simpleName) 15 | } 16 | 17 | override fun execute(namespace: String, clusterName: String, params: Int): Result { 18 | return try { 19 | val address = kubeClient.findFlinkAddress(flinkOptions, namespace, clusterName) 20 | 21 | val overview = flinkClient.getOverview(address) 22 | 23 | Result( 24 | ResultStatus.OK, 25 | overview.slotsTotal >= params 26 | ) 27 | } catch (e : Exception) { 28 | logger.log(Level.FINE, "Can't get server overview") 29 | 30 | Result( 31 | ResultStatus.ERROR, 32 | false 33 | ) 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/action/DeploymentDelete.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.action 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 5 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 6 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ClusterAction 7 | import com.nextbreakpoint.flink.controller.k8s.controller.core.Result 8 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ResultStatus 9 | import java.util.logging.Level 10 | import java.util.logging.Logger 11 | 12 | class DeploymentDelete(flinkOptions: FlinkOptions, flinkClient: FlinkClient, kubeClient: KubeClient) : ClusterAction(flinkOptions, flinkClient, kubeClient) { 13 | companion object { 14 | private val logger = Logger.getLogger(DeploymentDelete::class.simpleName) 15 | } 16 | 17 | override fun execute(namespace: String, clusterName: String, params: String): Result { 18 | return try { 19 | kubeClient.deleteDeployment(namespace, params) 20 | 21 | Result( 22 | ResultStatus.OK, 23 | null 24 | ) 25 | } catch (e : Exception) { 26 | logger.log(Level.SEVERE, "Can't delete supervisor deployment", e) 27 | 28 | Result( 29 | ResultStatus.ERROR, 30 | null 31 | ) 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/action/FlinkClusterCreate.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.action 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 5 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 6 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ClusterAction 7 | import com.nextbreakpoint.flink.controller.k8s.controller.core.Result 8 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ResultStatus 9 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkCluster 10 | import java.util.logging.Level 11 | import java.util.logging.Logger 12 | 13 | class FlinkClusterCreate(flinkOptions: FlinkOptions, flinkClient: FlinkClient, kubeClient: KubeClient) : ClusterAction(flinkOptions, flinkClient, kubeClient) { 14 | companion object { 15 | private val logger = Logger.getLogger(FlinkClusterCreate::class.simpleName) 16 | } 17 | 18 | override fun execute(namespace: String, clusterName: String, params: V1FlinkCluster): Result { 19 | return try { 20 | kubeClient.createFlinkCluster(namespace, params) 21 | 22 | Result( 23 | ResultStatus.OK, 24 | null 25 | ) 26 | } catch (e : Exception) { 27 | logger.log(Level.SEVERE, "Can't create cluster", e) 28 | 29 | Result( 30 | ResultStatus.ERROR, 31 | null 32 | ) 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/action/FlinkClusterDelete.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.action 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 5 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 6 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ClusterAction 7 | import com.nextbreakpoint.flink.controller.k8s.controller.core.Result 8 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ResultStatus 9 | import java.util.logging.Level 10 | import java.util.logging.Logger 11 | 12 | class FlinkClusterDelete(flinkOptions: FlinkOptions, flinkClient: FlinkClient, kubeClient: KubeClient) : ClusterAction(flinkOptions, flinkClient, kubeClient) { 13 | companion object { 14 | private val logger = Logger.getLogger(FlinkClusterDelete::class.simpleName) 15 | } 16 | 17 | override fun execute(namespace: String, clusterName: String, params: Void?): Result { 18 | return try { 19 | kubeClient.deleteFlinkCluster(namespace, clusterName) 20 | 21 | Result( 22 | ResultStatus.OK, 23 | null 24 | ) 25 | } catch (e : Exception) { 26 | logger.log(Level.SEVERE, "Can't delete cluster", e) 27 | 28 | Result( 29 | ResultStatus.ERROR, 30 | null 31 | ) 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/action/FlinkClusterGetStatus.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.action 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 5 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 6 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ClusterAction 7 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ClusterContext 8 | import com.nextbreakpoint.flink.controller.k8s.controller.core.Result 9 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ResultStatus 10 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkClusterStatus 11 | 12 | class FlinkClusterGetStatus(flinkOptions: FlinkOptions, flinkClient: FlinkClient, kubeClient: KubeClient, private val context: ClusterContext) : ClusterAction(flinkOptions, flinkClient, kubeClient) { 13 | override fun execute(namespace: String, clusterName: String, params: Void?): Result { 14 | return Result(ResultStatus.OK, context.getClusterStatus()) 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/action/FlinkClusterUpdate.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.action 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 5 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 6 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ClusterAction 7 | import com.nextbreakpoint.flink.controller.k8s.controller.core.Result 8 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ResultStatus 9 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkCluster 10 | import java.util.logging.Level 11 | import java.util.logging.Logger 12 | 13 | class FlinkClusterUpdate(flinkOptions: FlinkOptions, flinkClient: FlinkClient, kubeClient: KubeClient) : ClusterAction(flinkOptions, flinkClient, kubeClient) { 14 | companion object { 15 | private val logger = Logger.getLogger(FlinkClusterUpdate::class.simpleName) 16 | } 17 | 18 | override fun execute(namespace: String, clusterName: String, params: V1FlinkCluster): Result { 19 | return try { 20 | kubeClient.updateFlinkCluster(namespace, params) 21 | 22 | Result( 23 | ResultStatus.OK, 24 | null 25 | ) 26 | } catch (e : Exception) { 27 | logger.log(Level.SEVERE, "Can't update cluster", e) 28 | 29 | Result( 30 | ResultStatus.ERROR, 31 | null 32 | ) 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/action/FlinkDeploymentCreate.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.action 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 5 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 6 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ClusterAction 7 | import com.nextbreakpoint.flink.controller.k8s.controller.core.Result 8 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ResultStatus 9 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkDeployment 10 | import java.util.logging.Level 11 | import java.util.logging.Logger 12 | 13 | class FlinkDeploymentCreate(flinkOptions: FlinkOptions, flinkClient: FlinkClient, kubeClient: KubeClient) : ClusterAction(flinkOptions, flinkClient, kubeClient) { 14 | companion object { 15 | private val logger = Logger.getLogger(FlinkDeploymentCreate::class.simpleName) 16 | } 17 | 18 | override fun execute(namespace: String, clusterName: String, params: V1FlinkDeployment): Result { 19 | return try { 20 | kubeClient.createFlinkDeployment(namespace, params) 21 | 22 | Result( 23 | ResultStatus.OK, 24 | null 25 | ) 26 | } catch (e : Exception) { 27 | logger.log(Level.SEVERE, "Can't create deployment", e) 28 | 29 | Result( 30 | ResultStatus.ERROR, 31 | null 32 | ) 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/action/FlinkDeploymentDelete.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.action 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 5 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 6 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ClusterAction 7 | import com.nextbreakpoint.flink.controller.k8s.controller.core.Result 8 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ResultStatus 9 | import java.util.logging.Level 10 | import java.util.logging.Logger 11 | 12 | class FlinkDeploymentDelete(flinkOptions: FlinkOptions, flinkClient: FlinkClient, kubeClient: KubeClient) : ClusterAction(flinkOptions, flinkClient, kubeClient) { 13 | companion object { 14 | private val logger = Logger.getLogger(FlinkDeploymentDelete::class.simpleName) 15 | } 16 | 17 | override fun execute(namespace: String, clusterName: String, params: Void?): Result { 18 | return try { 19 | kubeClient.deleteFlinkDeployment(namespace, clusterName) 20 | 21 | Result( 22 | ResultStatus.OK, 23 | null 24 | ) 25 | } catch (e : Exception) { 26 | logger.log(Level.SEVERE, "Can't delete deployment", e) 27 | 28 | Result( 29 | ResultStatus.ERROR, 30 | null 31 | ) 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/action/FlinkDeploymentGetStatus.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.action 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 5 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 6 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ClusterAction 7 | import com.nextbreakpoint.flink.controller.k8s.controller.core.DeploymentContext 8 | import com.nextbreakpoint.flink.controller.k8s.controller.core.Result 9 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ResultStatus 10 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkDeploymentStatus 11 | 12 | class FlinkDeploymentGetStatus(flinkOptions: FlinkOptions, flinkClient: FlinkClient, kubeClient: KubeClient, private val context: DeploymentContext) : ClusterAction(flinkOptions, flinkClient, kubeClient) { 13 | override fun execute(namespace: String, clusterName: String, params: Void?): Result { 14 | return Result(ResultStatus.OK, context.getDeploymentStatus()) 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/action/FlinkDeploymentUpdate.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.action 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 5 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 6 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ClusterAction 7 | import com.nextbreakpoint.flink.controller.k8s.controller.core.Result 8 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ResultStatus 9 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkDeployment 10 | import java.util.logging.Level 11 | import java.util.logging.Logger 12 | 13 | class FlinkDeploymentUpdate(flinkOptions: FlinkOptions, flinkClient: FlinkClient, kubeClient: KubeClient) : ClusterAction(flinkOptions, flinkClient, kubeClient) { 14 | companion object { 15 | private val logger = Logger.getLogger(FlinkDeploymentUpdate::class.simpleName) 16 | } 17 | 18 | override fun execute(namespace: String, clusterName: String, params: V1FlinkDeployment): Result { 19 | return try { 20 | kubeClient.updateFlinkDeployment(namespace, params) 21 | 22 | Result( 23 | ResultStatus.OK, 24 | null 25 | ) 26 | } catch (e : Exception) { 27 | logger.log(Level.SEVERE, "Can't update deployment", e) 28 | 29 | Result( 30 | ResultStatus.ERROR, 31 | null 32 | ) 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/action/FlinkJobCreate.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.action 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 5 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 6 | import com.nextbreakpoint.flink.controller.k8s.controller.core.JobAction 7 | import com.nextbreakpoint.flink.controller.k8s.controller.core.Result 8 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ResultStatus 9 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkJob 10 | import java.util.logging.Level 11 | import java.util.logging.Logger 12 | 13 | class FlinkJobCreate(flinkOptions: FlinkOptions, flinkClient: FlinkClient, kubeClient: KubeClient) : JobAction(flinkOptions, flinkClient, kubeClient) { 14 | companion object { 15 | private val logger = Logger.getLogger(FlinkJobCreate::class.simpleName) 16 | } 17 | 18 | override fun execute(namespace: String, clusterName: String, jobName: String, params: V1FlinkJob): Result { 19 | return try { 20 | kubeClient.createFlinkJob(namespace, params) 21 | 22 | Result( 23 | ResultStatus.OK, 24 | null 25 | ) 26 | } catch (e : Exception) { 27 | logger.log(Level.SEVERE, "Can't create job", e) 28 | 29 | Result( 30 | ResultStatus.ERROR, 31 | null 32 | ) 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/action/FlinkJobDelete.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.action 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 5 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 6 | import com.nextbreakpoint.flink.controller.k8s.controller.core.JobAction 7 | import com.nextbreakpoint.flink.controller.k8s.controller.core.Result 8 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ResultStatus 9 | import java.util.logging.Level 10 | import java.util.logging.Logger 11 | 12 | class FlinkJobDelete(flinkOptions: FlinkOptions, flinkClient: FlinkClient, kubeClient: KubeClient) : JobAction(flinkOptions, flinkClient, kubeClient) { 13 | companion object { 14 | private val logger = Logger.getLogger(FlinkJobDelete::class.simpleName) 15 | } 16 | 17 | override fun execute(namespace: String, clusterName: String, jobName: String, params: Void?): Result { 18 | return try { 19 | kubeClient.deleteFlinkJob(namespace, "$clusterName-$jobName") 20 | 21 | Result( 22 | ResultStatus.OK, 23 | null 24 | ) 25 | } catch (e : Exception) { 26 | logger.log(Level.SEVERE, "Can't delete job", e) 27 | 28 | Result( 29 | ResultStatus.ERROR, 30 | null 31 | ) 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/action/FlinkJobGetStatus.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.action 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 5 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 6 | import com.nextbreakpoint.flink.controller.k8s.controller.core.JobAction 7 | import com.nextbreakpoint.flink.controller.k8s.controller.core.JobContext 8 | import com.nextbreakpoint.flink.controller.k8s.controller.core.Result 9 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ResultStatus 10 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkJobStatus 11 | 12 | class FlinkJobGetStatus(flinkOptions: FlinkOptions, flinkClient: FlinkClient, kubeClient: KubeClient, private val context: JobContext) : JobAction(flinkOptions, flinkClient, kubeClient) { 13 | override fun execute(namespace: String, clusterName: String, jobName: String, params: Void?): Result { 14 | return Result(ResultStatus.OK, context.getJobStatus()) 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/action/FlinkJobUpdate.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.action 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 5 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 6 | import com.nextbreakpoint.flink.controller.k8s.controller.core.JobAction 7 | import com.nextbreakpoint.flink.controller.k8s.controller.core.Result 8 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ResultStatus 9 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkJob 10 | import java.util.logging.Level 11 | import java.util.logging.Logger 12 | 13 | class FlinkJobUpdate(flinkOptions: FlinkOptions, flinkClient: FlinkClient, kubeClient: KubeClient) : JobAction(flinkOptions, flinkClient, kubeClient) { 14 | companion object { 15 | private val logger = Logger.getLogger(FlinkJobUpdate::class.simpleName) 16 | } 17 | 18 | override fun execute(namespace: String, clusterName: String, jobName: String, params: V1FlinkJob): Result { 19 | return try { 20 | kubeClient.updateFlinkJob(namespace, params) 21 | 22 | Result( 23 | ResultStatus.OK, 24 | null 25 | ) 26 | } catch (e : Exception) { 27 | logger.log(Level.SEVERE, "Can't update job", e) 28 | 29 | Result( 30 | ResultStatus.ERROR, 31 | null 32 | ) 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/action/PodCreate.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.action 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 5 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 6 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ClusterAction 7 | import com.nextbreakpoint.flink.controller.k8s.controller.core.Result 8 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ResultStatus 9 | import io.kubernetes.client.openapi.models.V1Pod 10 | import java.util.logging.Level 11 | import java.util.logging.Logger 12 | 13 | class PodCreate(flinkOptions: FlinkOptions, flinkClient: FlinkClient, kubeClient: KubeClient) : ClusterAction(flinkOptions, flinkClient, kubeClient) { 14 | companion object { 15 | private val logger = Logger.getLogger(PodCreate::class.simpleName) 16 | } 17 | 18 | override fun execute(namespace: String, clusterName: String, params: V1Pod): Result { 19 | return try { 20 | val podOut = kubeClient.createPod(namespace, params) 21 | 22 | Result( 23 | ResultStatus.OK, 24 | podOut.metadata?.name ?: throw RuntimeException("Unexpected metadata") 25 | ) 26 | } catch (e : Exception) { 27 | logger.log(Level.SEVERE, "Can't create pod", e) 28 | 29 | Result( 30 | ResultStatus.ERROR, 31 | null 32 | ) 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/action/PodDelete.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.action 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 5 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 6 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ClusterAction 7 | import com.nextbreakpoint.flink.controller.k8s.controller.core.Result 8 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ResultStatus 9 | import java.util.logging.Level 10 | import java.util.logging.Logger 11 | 12 | class PodDelete(flinkOptions: FlinkOptions, flinkClient: FlinkClient, kubeClient: KubeClient) : ClusterAction(flinkOptions, flinkClient, kubeClient) { 13 | companion object { 14 | private val logger = Logger.getLogger(PodDelete::class.simpleName) 15 | } 16 | 17 | override fun execute(namespace: String, clusterName: String, params: String): Result { 18 | return try { 19 | kubeClient.deletePod(namespace, params) 20 | 21 | Result( 22 | ResultStatus.OK, 23 | null 24 | ) 25 | } catch (e : Exception) { 26 | logger.log(Level.SEVERE, "Can't delete pod", e) 27 | 28 | Result( 29 | ResultStatus.ERROR, 30 | null 31 | ) 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/action/RequestClusterScale.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.action 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.common.ScaleClusterOptions 5 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 6 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 7 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ClusterAction 8 | import com.nextbreakpoint.flink.controller.k8s.controller.core.Result 9 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ResultStatus 10 | import java.util.logging.Level 11 | import java.util.logging.Logger 12 | 13 | class RequestClusterScale(flinkOptions: FlinkOptions, flinkClient: FlinkClient, kubeClient: KubeClient) : ClusterAction(flinkOptions, flinkClient, kubeClient) { 14 | companion object { 15 | private val logger = Logger.getLogger(RequestClusterScale::class.simpleName) 16 | } 17 | 18 | override fun execute(namespace: String, clusterName: String, params: ScaleClusterOptions): Result { 19 | return try { 20 | kubeClient.rescaleCluster(namespace, clusterName, params.taskManagers) 21 | 22 | Result( 23 | ResultStatus.OK, 24 | null 25 | ) 26 | } catch (e : Exception) { 27 | logger.log(Level.SEVERE, "Can't scale cluster", e) 28 | 29 | Result( 30 | ResultStatus.ERROR, 31 | null 32 | ) 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/action/RequestJobScale.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.action 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.common.ScaleJobOptions 5 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 6 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 7 | import com.nextbreakpoint.flink.controller.k8s.controller.core.JobAction 8 | import com.nextbreakpoint.flink.controller.k8s.controller.core.Result 9 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ResultStatus 10 | import java.util.logging.Level 11 | import java.util.logging.Logger 12 | 13 | class RequestJobScale(flinkOptions: FlinkOptions, flinkClient: FlinkClient, kubeClient: KubeClient) : JobAction(flinkOptions, flinkClient, kubeClient) { 14 | companion object { 15 | private val logger = Logger.getLogger(RequestJobScale::class.simpleName) 16 | } 17 | 18 | override fun execute(namespace: String, clusterName: String, jobName: String, params: ScaleJobOptions): Result { 19 | return try { 20 | kubeClient.rescaleJob(namespace, "$clusterName-$jobName", params.parallelism) 21 | 22 | Result( 23 | ResultStatus.OK, 24 | null 25 | ) 26 | } catch (e : Exception) { 27 | logger.log(Level.SEVERE, "Can't scale job", e) 28 | 29 | Result( 30 | ResultStatus.ERROR, 31 | null 32 | ) 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/action/ServiceDelete.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.action 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 5 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 6 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ClusterAction 7 | import com.nextbreakpoint.flink.controller.k8s.controller.core.Result 8 | import com.nextbreakpoint.flink.controller.k8s.controller.core.ResultStatus 9 | import java.util.logging.Level 10 | import java.util.logging.Logger 11 | 12 | class ServiceDelete(flinkOptions: FlinkOptions, flinkClient: FlinkClient, kubeClient: KubeClient) : ClusterAction(flinkOptions, flinkClient, kubeClient) { 13 | companion object { 14 | private val logger = Logger.getLogger(ServiceDelete::class.simpleName) 15 | } 16 | 17 | override fun execute(namespace: String, clusterName: String, params: String): Result { 18 | return try { 19 | kubeClient.deleteService(namespace, params) 20 | 21 | Result( 22 | ResultStatus.OK, 23 | null 24 | ) 25 | } catch (e : Exception) { 26 | logger.log(Level.SEVERE, "Can't delete service", e) 27 | 28 | Result( 29 | ResultStatus.ERROR, 30 | null 31 | ) 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/core/ClusterAction.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.core 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 5 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 6 | 7 | abstract class ClusterAction(val flinkOptions: FlinkOptions, val flinkClient: FlinkClient, val kubeClient: KubeClient) { 8 | abstract fun execute(namespace: String, clusterName: String, params: T): Result 9 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/core/ClusterContext.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.core 2 | 3 | import com.nextbreakpoint.flink.controller.common.Action 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClusterAnnotations 5 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkCluster 6 | 7 | class ClusterContext(private val cluster: V1FlinkCluster) { 8 | fun setClusterWithoutSavepoint(withoutSavepoint: Boolean) { 9 | FlinkClusterAnnotations.setWithoutSavepoint(cluster, withoutSavepoint) 10 | } 11 | 12 | fun setClusterManualAction(action: Action) { 13 | FlinkClusterAnnotations.setRequestedAction(cluster, action) 14 | } 15 | 16 | // the returned map must be immutable to avoid side effects 17 | fun getClusterAnnotations() = cluster.metadata?.annotations?.toMap().orEmpty() 18 | 19 | // we should make copy of status to avoid side effects 20 | fun getClusterStatus() = cluster.status 21 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/core/DeploymentContext.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.core 2 | 3 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkDeployment 4 | 5 | class DeploymentContext(private val deployment: V1FlinkDeployment) { 6 | // we should make copy of status to avoid side effects 7 | fun getDeploymentStatus() = deployment.status 8 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/core/JobAction.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.core 2 | 3 | import com.nextbreakpoint.flink.controller.common.FlinkOptions 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkClient 5 | import com.nextbreakpoint.flink.controller.k8s.common.KubeClient 6 | 7 | abstract class JobAction(val flinkOptions: FlinkOptions, val flinkClient: FlinkClient, val kubeClient: KubeClient) { 8 | abstract fun execute(namespace: String, clusterName: String, jobName: String, params: T): Result 9 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/core/JobContext.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.core 2 | 3 | import com.nextbreakpoint.flink.controller.common.Action 4 | import com.nextbreakpoint.flink.controller.k8s.common.FlinkJobAnnotations 5 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkJob 6 | 7 | class JobContext(private val job: V1FlinkJob) { 8 | fun setJobWithoutSavepoint(withoutSavepoint: Boolean) { 9 | FlinkJobAnnotations.setWithoutSavepoint(job, withoutSavepoint) 10 | } 11 | 12 | fun setJobManualAction(action: Action) { 13 | FlinkJobAnnotations.setRequestedAction(job, action) 14 | } 15 | 16 | // the returned map must be immutable to avoid side effects 17 | fun getJobAnnotations() = job.metadata?.annotations?.toMap().orEmpty() 18 | 19 | // we should make copy of status to avoid side effects 20 | fun getJobStatus() = job.status 21 | 22 | fun getJobId() = job.status.jobId 23 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/core/Result.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.core 2 | 3 | data class Result(val status: ResultStatus, val output: T) { 4 | fun isSuccessful() = status == ResultStatus.OK 5 | } 6 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/core/ResultStatus.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.core 2 | 3 | enum class ResultStatus { 4 | OK, ERROR 5 | } 6 | -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/operator/core/SupervisorResources.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.operator.core 2 | 3 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkCluster 4 | import io.kubernetes.client.openapi.models.V1Deployment 5 | import io.kubernetes.client.openapi.models.V1Pod 6 | 7 | data class SupervisorResources( 8 | val flinkCluster: V1FlinkCluster? = null, 9 | val supervisorDep: V1Deployment? = null, 10 | val supervisorPods: Set 11 | ) -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/supervisor/core/ClusterResources.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.supervisor.core 2 | 3 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkCluster 4 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkJob 5 | import io.kubernetes.client.openapi.models.V1Pod 6 | import io.kubernetes.client.openapi.models.V1Service 7 | 8 | data class ClusterResources( 9 | val flinkCluster: V1FlinkCluster? = null, 10 | val jobmanagerPods: Set = setOf(), 11 | val taskmanagerPods: Set = setOf(), 12 | val jobmanagerService: V1Service? = null, 13 | val flinkJobs: Set = setOf() 14 | ) { 15 | fun withService(resource: V1Service?) = 16 | ClusterResources( 17 | flinkCluster = this.flinkCluster, 18 | jobmanagerPods = this.jobmanagerPods, 19 | taskmanagerPods = this.taskmanagerPods, 20 | jobmanagerService = resource, 21 | flinkJobs = this.flinkJobs 22 | ) 23 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/supervisor/core/JobResources.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.supervisor.core 2 | 3 | import com.nextbreakpoint.flink.controller.k8s.crd.V1FlinkJob 4 | import io.kubernetes.client.openapi.models.V1Job 5 | 6 | data class JobResources( 7 | val flinkJob: V1FlinkJob? = null, 8 | val bootstrapJob: V1Job? = null 9 | ) { 10 | fun withBootstrap(resource: V1Job?) = 11 | JobResources( 12 | flinkJob = this.flinkJob, 13 | bootstrapJob = resource 14 | ) 15 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/supervisor/task/ClusterOnInitialize.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.supervisor.task 2 | 3 | import com.nextbreakpoint.flink.controller.k8s.common.Task 4 | import com.nextbreakpoint.flink.controller.k8s.supervisor.core.ClusterManager 5 | 6 | class ClusterOnInitialize : Task() { 7 | override fun execute(manager: ClusterManager) { 8 | if (!manager.hasFinalizer()) { 9 | if (manager.isResourceDeleted()) { 10 | manager.onClusterTerminated() 11 | } else { 12 | manager.addFinalizer() 13 | } 14 | } else { 15 | manager.onResourceInitialise() 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/supervisor/task/ClusterOnStarting.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.supervisor.task 2 | 3 | import com.nextbreakpoint.flink.controller.common.Action 4 | import com.nextbreakpoint.flink.controller.k8s.common.Task 5 | import com.nextbreakpoint.flink.controller.k8s.supervisor.core.ClusterManager 6 | 7 | class ClusterOnStarting : Task() { 8 | private val actions = setOf( 9 | Action.STOP 10 | ) 11 | 12 | override fun execute(manager: ClusterManager) { 13 | if (manager.isResourceDeleted()) { 14 | manager.onResourceDeleted() 15 | return 16 | } 17 | 18 | if (manager.hasSpecificationChanged()) { 19 | manager.onResourceChanged() 20 | return 21 | } 22 | 23 | if (manager.isActionPresent()) { 24 | manager.executeAction(actions) 25 | return 26 | } 27 | 28 | manager.setClusterHealth("") 29 | 30 | if (!manager.ensureJobManagerPodExists()) { 31 | return 32 | } 33 | 34 | if (!manager.ensureJobManagerServiceExists()) { 35 | return 36 | } 37 | 38 | if (!manager.isClusterHealthy()) { 39 | return 40 | } 41 | 42 | if (!manager.stopAllJobs()) { 43 | return 44 | } 45 | 46 | manager.onClusterStarted() 47 | } 48 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/supervisor/task/ClusterOnStopped.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.supervisor.task 2 | 3 | import com.nextbreakpoint.flink.controller.common.Action 4 | import com.nextbreakpoint.flink.controller.k8s.common.Task 5 | import com.nextbreakpoint.flink.controller.k8s.supervisor.core.ClusterManager 6 | 7 | class ClusterOnStopped : Task() { 8 | private val actions = setOf( 9 | Action.START 10 | ) 11 | 12 | override fun execute(manager: ClusterManager) { 13 | if (manager.isResourceDeleted()) { 14 | manager.onResourceDeleted() 15 | return 16 | } 17 | 18 | if (manager.isActionPresent()) { 19 | manager.executeAction(actions) 20 | return 21 | } 22 | 23 | manager.setClusterHealth("") 24 | 25 | if (manager.stopCluster()) { 26 | manager.setResourceUpdated(true) 27 | } else { 28 | manager.setResourceUpdated(false) 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/supervisor/task/ClusterOnStopping.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.supervisor.task 2 | 3 | import com.nextbreakpoint.flink.controller.common.Action 4 | import com.nextbreakpoint.flink.controller.k8s.common.Task 5 | import com.nextbreakpoint.flink.controller.k8s.supervisor.core.ClusterManager 6 | 7 | class ClusterOnStopping : Task() { 8 | private val actions = setOf( 9 | Action.START 10 | ) 11 | 12 | override fun execute(manager: ClusterManager) { 13 | if (!manager.waitForJobs()) { 14 | return 15 | } 16 | 17 | manager.setClusterHealth("") 18 | 19 | if (!manager.stopCluster()) { 20 | return 21 | } 22 | 23 | if (manager.mustTerminateResources()) { 24 | manager.onClusterTerminated() 25 | return 26 | } 27 | 28 | if (manager.shouldRestart()) { 29 | manager.onClusterReadyToRestart() 30 | return 31 | } 32 | 33 | if (manager.isActionPresent()) { 34 | manager.executeAction(actions) 35 | return 36 | } 37 | 38 | manager.onClusterStopped() 39 | } 40 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/supervisor/task/ClusterOnTerminated.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.supervisor.task 2 | 3 | import com.nextbreakpoint.flink.controller.k8s.common.Task 4 | import com.nextbreakpoint.flink.controller.k8s.supervisor.core.ClusterManager 5 | 6 | class ClusterOnTerminated : Task() { 7 | override fun execute(manager: ClusterManager) { 8 | if (manager.hasJobFinalizers()) { 9 | return 10 | } 11 | 12 | if (manager.hasFinalizer()) { 13 | manager.removeFinalizer() 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/supervisor/task/JobOnInitialise.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.supervisor.task 2 | 3 | import com.nextbreakpoint.flink.controller.k8s.common.Task 4 | import com.nextbreakpoint.flink.controller.k8s.supervisor.core.JobManager 5 | 6 | class JobOnInitialise : Task() { 7 | override fun execute(manager: JobManager) { 8 | if (manager.isClusterTerminated()) { 9 | return 10 | } 11 | 12 | if (!manager.hasFinalizer()) { 13 | if (manager.isResourceDeleted()) { 14 | manager.onJobTerminated() 15 | } else { 16 | manager.addFinalizer() 17 | } 18 | } else { 19 | manager.onResourceInitialise() 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/supervisor/task/JobOnStopping.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.supervisor.task 2 | 3 | import com.nextbreakpoint.flink.controller.k8s.common.Task 4 | import com.nextbreakpoint.flink.controller.k8s.supervisor.core.JobManager 5 | 6 | class JobOnStopping : Task() { 7 | override fun execute(manager: JobManager) { 8 | if (!manager.terminateBootstrapJob()) { 9 | return 10 | } 11 | 12 | if (manager.isClusterStarted()) { 13 | manager.setClusterHealth("HEALTHY") 14 | } else { 15 | manager.setClusterHealth("") 16 | } 17 | 18 | if (manager.isClusterUnhealthy()) { 19 | manager.setClusterHealth("UNHEALTHY") 20 | if (manager.mustTerminateResources()) { 21 | manager.onJobTerminated() 22 | } else { 23 | manager.onJobStopped() 24 | } 25 | return 26 | } 27 | 28 | if (!manager.cancelJob()) { 29 | return 30 | } 31 | 32 | if (manager.mustTerminateResources()) { 33 | manager.onJobTerminated() 34 | } else { 35 | if (manager.shouldRestart()) { 36 | manager.onJobReadyToRestart() 37 | } else { 38 | manager.onJobStopped() 39 | } 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/k8s/supervisor/task/JobOnTerminated.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.supervisor.task 2 | 3 | import com.nextbreakpoint.flink.controller.k8s.common.Task 4 | import com.nextbreakpoint.flink.controller.k8s.supervisor.core.JobManager 5 | 6 | class JobOnTerminated : Task() { 7 | override fun execute(manager: JobManager) { 8 | if (manager.hasFinalizer()) { 9 | manager.removeFinalizer() 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/vertex/core/ClusterCommand.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.vertex.core 2 | 3 | import com.nextbreakpoint.flink.controller.common.ClusterSelector 4 | 5 | data class ClusterCommand(val selector: ClusterSelector, val json: String) -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/vertex/core/DeploymentCommand.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.vertex.core 2 | 3 | import com.nextbreakpoint.flink.controller.common.DeploymentSelector 4 | 5 | data class DeploymentCommand(val selector: DeploymentSelector, val json: String) -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/vertex/core/JobCommand.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.vertex.core 2 | 3 | import com.nextbreakpoint.flink.controller.common.JobSelector 4 | 5 | data class JobCommand(val selector: JobSelector, val json: String) -------------------------------------------------------------------------------- /src/main/kotlin/com/nextbreakpoint/flink/controller/vertex/core/Timeout.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.vertex.core 2 | 3 | object Timeout { 4 | val POLLING_INTERVAL = System.getenv("POLLING_INTERVAL")?.toLong() ?: 5L 5 | } 6 | -------------------------------------------------------------------------------- /src/main/lombok/com/nextbreakpoint/flink/controller/k8s/crd/V1BootstrapSpec.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.crd; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import io.kubernetes.client.openapi.models.V1ResourceRequirements; 5 | import io.kubernetes.client.openapi.models.V1SecurityContext; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.AllArgsConstructor; 9 | import lombok.NoArgsConstructor; 10 | 11 | import java.util.List; 12 | 13 | @Data 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | @Builder(toBuilder = true, setterPrefix = "with") 17 | public class V1BootstrapSpec { 18 | @SerializedName("pullSecrets") 19 | private String pullSecrets; 20 | @SerializedName("pullPolicy") 21 | private String pullPolicy; 22 | @SerializedName("image") 23 | private String image; 24 | @SerializedName("className") 25 | private String className; 26 | @SerializedName("jarPath") 27 | private String jarPath; 28 | @SerializedName("arguments") 29 | private List arguments; 30 | @SerializedName("serviceAccount") 31 | private String serviceAccount; 32 | @SerializedName("resources") 33 | private V1ResourceRequirements resources; 34 | @SerializedName("securityContext") 35 | private V1SecurityContext securityContext; 36 | } 37 | -------------------------------------------------------------------------------- /src/main/lombok/com/nextbreakpoint/flink/controller/k8s/crd/V1FlinkCluster.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.crd; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import io.kubernetes.client.common.KubernetesObject; 5 | import io.kubernetes.client.openapi.models.V1ObjectMeta; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.AllArgsConstructor; 9 | import lombok.NoArgsConstructor; 10 | 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | @Builder(toBuilder = true, setterPrefix = "with") 15 | public class V1FlinkCluster implements KubernetesObject { 16 | @SerializedName("apiVersion") 17 | private String apiVersion; 18 | @SerializedName("kind") 19 | private String kind; 20 | @SerializedName("metadata") 21 | private V1ObjectMeta metadata; 22 | @SerializedName("status") 23 | private V1FlinkClusterStatus status; 24 | @SerializedName("spec") 25 | private V1FlinkClusterSpec spec; 26 | } 27 | -------------------------------------------------------------------------------- /src/main/lombok/com/nextbreakpoint/flink/controller/k8s/crd/V1FlinkClusterDigest.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.crd; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.AllArgsConstructor; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | @Builder(toBuilder = true, setterPrefix = "with") 13 | public class V1FlinkClusterDigest { 14 | @SerializedName("runtime") 15 | private String runtime; 16 | @SerializedName("jobManager") 17 | private String jobManager; 18 | @SerializedName("taskManager") 19 | private String taskManager; 20 | @SerializedName("supervisor") 21 | private String supervisor; 22 | } 23 | -------------------------------------------------------------------------------- /src/main/lombok/com/nextbreakpoint/flink/controller/k8s/crd/V1FlinkClusterList.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.crd; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import io.kubernetes.client.common.KubernetesListObject; 5 | import io.kubernetes.client.openapi.models.V1ListMeta; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.AllArgsConstructor; 9 | import lombok.NoArgsConstructor; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | @Builder(toBuilder = true, setterPrefix = "with") 18 | public class V1FlinkClusterList implements KubernetesListObject { 19 | @SerializedName("apiVersion") 20 | private String apiVersion; 21 | @SerializedName("items") 22 | @Builder.Default 23 | private List items = new ArrayList<>(); 24 | @SerializedName("kind") 25 | private String kind; 26 | @SerializedName("metadata") 27 | private V1ListMeta metadata; 28 | 29 | public V1FlinkClusterList items(List items) { 30 | this.items = items; 31 | return this; 32 | } 33 | 34 | public V1FlinkClusterList addItemsItem(V1FlinkCluster itemsItem) { 35 | this.items.add(itemsItem); 36 | return this; 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/lombok/com/nextbreakpoint/flink/controller/k8s/crd/V1FlinkClusterSpec.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.crd; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.AllArgsConstructor; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | @Builder(toBuilder = true, setterPrefix = "with") 13 | public class V1FlinkClusterSpec { 14 | @SerializedName("runtime") 15 | private V1RuntimeSpec runtime; 16 | @SerializedName("jobManager") 17 | private V1JobManagerSpec jobManager; 18 | @SerializedName("taskManager") 19 | private V1TaskManagerSpec taskManager; 20 | @SerializedName("supervisor") 21 | private V1SupervisorSpec supervisor; 22 | @SerializedName("taskManagers") 23 | private Integer taskManagers; 24 | @SerializedName("minTaskManagers") 25 | private Integer minTaskManagers; 26 | @SerializedName("maxTaskManagers") 27 | private Integer maxTaskManagers; 28 | } 29 | -------------------------------------------------------------------------------- /src/main/lombok/com/nextbreakpoint/flink/controller/k8s/crd/V1FlinkClusterStatus.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.crd; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.AllArgsConstructor; 7 | import lombok.NoArgsConstructor; 8 | import java.time.OffsetDateTime; 9 | 10 | @Data 11 | @AllArgsConstructor 12 | @NoArgsConstructor 13 | @Builder(toBuilder = true, setterPrefix = "with") 14 | public class V1FlinkClusterStatus { 15 | @SerializedName("resourceStatus") 16 | private String resourceStatus; 17 | @SerializedName("supervisorStatus") 18 | private String supervisorStatus; 19 | @SerializedName("labelSelector") 20 | private String labelSelector; 21 | @SerializedName("clusterHealth") 22 | private String clusterHealth; 23 | @SerializedName("taskManagers") 24 | private Integer taskManagers; 25 | @SerializedName("taskSlots") 26 | private Integer taskSlots; 27 | @SerializedName("taskManagerReplicas") 28 | private Integer taskManagerReplicas; 29 | @SerializedName("totalTaskSlots") 30 | private Integer totalTaskSlots; 31 | @SerializedName("timestamp") 32 | private OffsetDateTime timestamp; 33 | @SerializedName("serviceMode") 34 | private String serviceMode; 35 | @SerializedName("digest") 36 | private V1FlinkClusterDigest digest; 37 | @SerializedName("rescaleTimestamp") 38 | private OffsetDateTime rescaleTimestamp; 39 | } -------------------------------------------------------------------------------- /src/main/lombok/com/nextbreakpoint/flink/controller/k8s/crd/V1FlinkDeployment.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.crd; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import io.kubernetes.client.common.KubernetesObject; 5 | import io.kubernetes.client.openapi.models.V1ObjectMeta; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.AllArgsConstructor; 9 | import lombok.NoArgsConstructor; 10 | 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | @Builder(toBuilder = true, setterPrefix = "with") 15 | public class V1FlinkDeployment implements KubernetesObject { 16 | @SerializedName("apiVersion") 17 | private String apiVersion; 18 | @SerializedName("kind") 19 | private String kind; 20 | @SerializedName("metadata") 21 | private V1ObjectMeta metadata; 22 | @SerializedName("status") 23 | private V1FlinkDeploymentStatus status; 24 | @SerializedName("spec") 25 | private V1FlinkDeploymentSpec spec; 26 | } 27 | -------------------------------------------------------------------------------- /src/main/lombok/com/nextbreakpoint/flink/controller/k8s/crd/V1FlinkDeploymentDigest.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.crd; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.AllArgsConstructor; 7 | import lombok.NoArgsConstructor; 8 | 9 | import java.util.List; 10 | 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | @Builder(toBuilder = true, setterPrefix = "with") 15 | public class V1FlinkDeploymentDigest { 16 | @SerializedName("cluster") 17 | private V1FlinkClusterDigest cluster; 18 | @SerializedName("jobs") 19 | private List jobs; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/lombok/com/nextbreakpoint/flink/controller/k8s/crd/V1FlinkDeploymentJobDigest.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.crd; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.AllArgsConstructor; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | @Builder(toBuilder = true, setterPrefix = "with") 13 | public class V1FlinkDeploymentJobDigest { 14 | @SerializedName("name") 15 | private String name; 16 | @SerializedName("job") 17 | private V1FlinkJobDigest job; 18 | } 19 | -------------------------------------------------------------------------------- /src/main/lombok/com/nextbreakpoint/flink/controller/k8s/crd/V1FlinkDeploymentJobSpec.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.crd; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.AllArgsConstructor; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | @Builder(toBuilder = true, setterPrefix = "with") 13 | public class V1FlinkDeploymentJobSpec { 14 | @SerializedName("name") 15 | private String name; 16 | @SerializedName("spec") 17 | private V1FlinkJobSpec spec; 18 | } -------------------------------------------------------------------------------- /src/main/lombok/com/nextbreakpoint/flink/controller/k8s/crd/V1FlinkDeploymentList.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.crd; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import io.kubernetes.client.common.KubernetesListObject; 5 | import io.kubernetes.client.openapi.models.V1ListMeta; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.AllArgsConstructor; 9 | import lombok.NoArgsConstructor; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | @Builder(toBuilder = true, setterPrefix = "with") 18 | public class V1FlinkDeploymentList implements KubernetesListObject { 19 | @SerializedName("apiVersion") 20 | private String apiVersion; 21 | @SerializedName("items") 22 | @Builder.Default 23 | private List items = new ArrayList<>(); 24 | @SerializedName("kind") 25 | private String kind; 26 | @SerializedName("metadata") 27 | private V1ListMeta metadata; 28 | 29 | public V1FlinkDeploymentList items(List items) { 30 | this.items = items; 31 | return this; 32 | } 33 | 34 | public V1FlinkDeploymentList addItemsItem(V1FlinkDeployment itemsItem) { 35 | this.items.add(itemsItem); 36 | return this; 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/lombok/com/nextbreakpoint/flink/controller/k8s/crd/V1FlinkDeploymentSpec.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.crd; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.AllArgsConstructor; 7 | import lombok.NoArgsConstructor; 8 | 9 | import java.util.List; 10 | 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | @Builder(toBuilder = true, setterPrefix = "with") 15 | public class V1FlinkDeploymentSpec { 16 | @SerializedName("cluster") 17 | private V1FlinkClusterSpec cluster; 18 | @SerializedName("jobs") 19 | private List jobs; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/lombok/com/nextbreakpoint/flink/controller/k8s/crd/V1FlinkDeploymentStatus.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.crd; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.AllArgsConstructor; 7 | import lombok.NoArgsConstructor; 8 | import java.time.OffsetDateTime; 9 | 10 | @Data 11 | @AllArgsConstructor 12 | @NoArgsConstructor 13 | @Builder(toBuilder = true, setterPrefix = "with") 14 | public class V1FlinkDeploymentStatus { 15 | @SerializedName("resourceStatus") 16 | private String resourceStatus; 17 | @SerializedName("timestamp") 18 | private OffsetDateTime timestamp; 19 | @SerializedName("digest") 20 | private V1FlinkDeploymentDigest digest; 21 | } 22 | -------------------------------------------------------------------------------- /src/main/lombok/com/nextbreakpoint/flink/controller/k8s/crd/V1FlinkJob.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.crd; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import io.kubernetes.client.common.KubernetesObject; 5 | import io.kubernetes.client.openapi.models.V1ObjectMeta; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.AllArgsConstructor; 9 | import lombok.NoArgsConstructor; 10 | 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | @Builder(toBuilder = true, setterPrefix = "with") 15 | public class V1FlinkJob implements KubernetesObject { 16 | @SerializedName("apiVersion") 17 | private String apiVersion; 18 | @SerializedName("kind") 19 | private String kind; 20 | @SerializedName("metadata") 21 | private V1ObjectMeta metadata; 22 | @SerializedName("status") 23 | private V1FlinkJobStatus status; 24 | @SerializedName("spec") 25 | private V1FlinkJobSpec spec; 26 | } 27 | -------------------------------------------------------------------------------- /src/main/lombok/com/nextbreakpoint/flink/controller/k8s/crd/V1FlinkJobDigest.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.crd; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.AllArgsConstructor; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | @Builder(toBuilder = true, setterPrefix = "with") 13 | public class V1FlinkJobDigest { 14 | @SerializedName("bootstrap") 15 | private String bootstrap; 16 | @SerializedName("savepoint") 17 | private String savepoint; 18 | @SerializedName("restart") 19 | private String restart; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/lombok/com/nextbreakpoint/flink/controller/k8s/crd/V1FlinkJobList.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.crd; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import io.kubernetes.client.common.KubernetesListObject; 5 | import io.kubernetes.client.openapi.models.V1ListMeta; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.AllArgsConstructor; 9 | import lombok.NoArgsConstructor; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | @Builder(toBuilder = true, setterPrefix = "with") 18 | public class V1FlinkJobList implements KubernetesListObject { 19 | @SerializedName("apiVersion") 20 | private String apiVersion; 21 | @SerializedName("items") 22 | @Builder.Default 23 | private List items = new ArrayList<>(); 24 | @SerializedName("kind") 25 | private String kind; 26 | @SerializedName("metadata") 27 | private V1ListMeta metadata; 28 | 29 | public V1FlinkJobList items(List items) { 30 | this.items = items; 31 | return this; 32 | } 33 | 34 | public V1FlinkJobList addItemsItem(V1FlinkJob itemsItem) { 35 | this.items.add(itemsItem); 36 | return this; 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/lombok/com/nextbreakpoint/flink/controller/k8s/crd/V1FlinkJobSpec.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.crd; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.AllArgsConstructor; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | @Builder(toBuilder = true, setterPrefix = "with") 13 | public class V1FlinkJobSpec { 14 | @SerializedName("bootstrap") 15 | private V1BootstrapSpec bootstrap; 16 | @SerializedName("savepoint") 17 | private V1SavepointSpec savepoint; 18 | @SerializedName("restart") 19 | private V1RestartSpec restart; 20 | @SerializedName("jobParallelism") 21 | private Integer jobParallelism; 22 | @SerializedName("minJobParallelism") 23 | private Integer minJobParallelism; 24 | @SerializedName("maxJobParallelism") 25 | private Integer maxJobParallelism; 26 | } 27 | -------------------------------------------------------------------------------- /src/main/lombok/com/nextbreakpoint/flink/controller/k8s/crd/V1RestartSpec.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.crd; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.AllArgsConstructor; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | @Builder(toBuilder = true, setterPrefix = "with") 13 | public class V1RestartSpec { 14 | @SerializedName("restartPolicy") 15 | private String restartPolicy; 16 | @SerializedName("restartDelay") 17 | private Long restartDelay; 18 | @SerializedName("restartTimeout") 19 | private Long restartTimeout; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/lombok/com/nextbreakpoint/flink/controller/k8s/crd/V1RuntimeSpec.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.crd; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.AllArgsConstructor; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | @Builder(toBuilder = true, setterPrefix = "with") 13 | public class V1RuntimeSpec { 14 | @SerializedName("pullSecrets") 15 | private String pullSecrets; 16 | @SerializedName("pullPolicy") 17 | private String pullPolicy; 18 | @SerializedName("image") 19 | private String image; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/lombok/com/nextbreakpoint/flink/controller/k8s/crd/V1SavepointSpec.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.crd; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.AllArgsConstructor; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | @Builder(toBuilder = true, setterPrefix = "with") 13 | public class V1SavepointSpec { 14 | @SerializedName("savepointMode") 15 | private String savepointMode; 16 | @SerializedName("savepointPath") 17 | private String savepointPath; 18 | @SerializedName("savepointInterval") 19 | private Long savepointInterval; 20 | @SerializedName("savepointTargetPath") 21 | private String savepointTargetPath; 22 | } 23 | -------------------------------------------------------------------------------- /src/main/lombok/com/nextbreakpoint/flink/controller/k8s/crd/V1SupervisorSpec.java: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.crd; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import io.kubernetes.client.openapi.models.V1ResourceRequirements; 5 | import io.kubernetes.client.openapi.models.V1SecurityContext; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.AllArgsConstructor; 9 | import lombok.NoArgsConstructor; 10 | 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | @Builder(toBuilder = true, setterPrefix = "with") 15 | public class V1SupervisorSpec { 16 | @SerializedName("pullSecrets") 17 | private String pullSecrets; 18 | @SerializedName("pullPolicy") 19 | private String pullPolicy; 20 | @SerializedName("image") 21 | private String image; 22 | @SerializedName("serviceAccount") 23 | private String serviceAccount; 24 | @SerializedName("pollingInterval") 25 | private Integer pollingInterval; 26 | @SerializedName("taskTimeout") 27 | private Integer taskTimeout; 28 | @SerializedName("maxTaskManagers") 29 | private Integer maxTaskManagers; 30 | @SerializedName("resources") 31 | private V1ResourceRequirements resources; 32 | @SerializedName("rescaleDelay") 33 | private Integer rescaleDelay; 34 | @SerializedName("rescalePolicy") 35 | private String rescalePolicy; 36 | @SerializedName("replicas") 37 | private Integer replicas; 38 | @SerializedName("securityContext") 39 | private V1SecurityContext securityContext; 40 | } 41 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019-2024, Andrea Medeghini 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the copyright holder nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | name=@name@ 2 | version=@version@ 3 | -------------------------------------------------------------------------------- /src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/test/kotlin/com/nextbreakpoint/flink/controller/k8s/controller/core/ClusterActionResultTest.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.controller.core 2 | 3 | import org.assertj.core.api.Assertions.assertThat 4 | import org.junit.jupiter.api.Test 5 | 6 | class ClusterActionResultTest { 7 | @Test 8 | fun `should return true when completed otherwise false`() { 9 | val result = Result(status = ResultStatus.OK, output = "123") 10 | assertThat(result.isSuccessful()).isTrue() 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/kotlin/com/nextbreakpoint/flink/controller/k8s/supervisor/task/JobOnTerminatedTest.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.k8s.supervisor.task 2 | 3 | import com.nextbreakpoint.flink.controller.k8s.supervisor.core.JobManager 4 | import com.nextbreakpoint.flink.controller.testing.KotlinMockito.given 5 | import org.junit.jupiter.api.Test 6 | import org.mockito.Mockito.mock 7 | import org.mockito.Mockito.times 8 | import org.mockito.Mockito.verify 9 | import org.mockito.Mockito.verifyNoMoreInteractions 10 | 11 | class JobOnTerminatedTest { 12 | private val context = mock(JobManager::class.java) 13 | private val task = JobOnTerminated() 14 | 15 | @Test 16 | fun `should remove finalizer if not removed`() { 17 | given(context.hasFinalizer()).thenReturn(true) 18 | task.execute(context) 19 | verify(context, times(1)).hasFinalizer() 20 | verify(context, times(1)).removeFinalizer() 21 | verifyNoMoreInteractions(context) 22 | } 23 | 24 | @Test 25 | fun `should not remove finalizer if already removed`() { 26 | given(context.hasFinalizer()).thenReturn(false) 27 | task.execute(context) 28 | verify(context, times(1)).hasFinalizer() 29 | verifyNoMoreInteractions(context) 30 | } 31 | } -------------------------------------------------------------------------------- /src/test/kotlin/com/nextbreakpoint/flink/controller/testing/KotlinMockito.kt: -------------------------------------------------------------------------------- 1 | package com.nextbreakpoint.flink.controller.testing 2 | 3 | import org.mockito.Mockito 4 | import org.mockito.Mockito.`when` 5 | import org.mockito.stubbing.OngoingStubbing 6 | 7 | object KotlinMockito { 8 | fun any(): T { 9 | Mockito.any() 10 | return uninitialized() 11 | } 12 | 13 | fun eq(value : T): T { 14 | Mockito.eq(value) 15 | return value ?: uninitialized() 16 | } 17 | 18 | fun given(value : T): OngoingStubbing = `when`(value) 19 | 20 | @Suppress("UNCHECKED_CAST") 21 | private fun uninitialized(): T = null as T 22 | } -------------------------------------------------------------------------------- /src/test/resources/job.json: -------------------------------------------------------------------------------- 1 | { 2 | "jobParallelism": 2, 3 | "bootstrap": { 4 | "serviceAccount": "bootstrap-test", 5 | "pullSecrets": "bootstrap-regcred", 6 | "pullPolicy": "IfNotPresent", 7 | "image": "registry:30000/jobs:latest", 8 | "jarPath": "/flink-jobs.jar", 9 | "className": "com.nextbreakpoint.flink.controller.jobs.stream.TestJob", 10 | "arguments": [ 11 | "--BUCKET_BASE_PATH", 12 | "file:///var/tmp" 13 | ] 14 | }, 15 | "savepoint": { 16 | "savepointMode": "Automatic", 17 | "savepointInterval": "60", 18 | "savepointTargetPath": "file:///var/tmp/test" 19 | }, 20 | "restart": { 21 | "restartPolicy": "Never", 22 | "restartDelay": 60, 23 | "restartTimeout": 120 24 | } 25 | } -------------------------------------------------------------------------------- /src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker: -------------------------------------------------------------------------------- 1 | mock-maker-inline -------------------------------------------------------------------------------- /toolchains-docker.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | jdk 4 | 5 | 21 6 | openjdk 7 | 8 | 9 | /opt/java/openjdk 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /toolchains-linux.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | jdk 4 | 5 | 21 6 | temurin 7 | 8 | 9 | /usr/lib/jvm/temurin-21-jdk-amd64 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /toolchains-osx.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | jdk 4 | 5 | 21 6 | temurin 7 | 8 | 9 | /Library/Java/JavaVirtualMachines/temurin-21.jdk/Contents/Home 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /toolchains-pipeline.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | jdk 4 | 5 | 21 6 | temurin 7 | 8 | 9 | /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/21.0.5-11.0.LTS/x64 10 | 11 | 12 | 13 | --------------------------------------------------------------------------------