Skip to content

Commit

Permalink
merged prof. kulkarni's changes, added asserts, and incorporated sugg…
Browse files Browse the repository at this point in the history
…estions on plugins/appstatus.py
  • Loading branch information
omgoswami committed Aug 5, 2024
2 parents ffd6500 + b0634dc commit 9ed594c
Show file tree
Hide file tree
Showing 27 changed files with 684 additions and 216 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ jobs:
cd $KUBEPLUS_HOME/platform-operator
./build-artifact.sh latest
#echo "Building kubeconfiggenerator..."
#cd $KUBEPLUS_HOME/deploy
#./build-artifact-kubeconfiggenerator.sh latest
echo "Building kubeconfiggenerator..."
cd $KUBEPLUS_HOME/deploy
./build-artifact-kubeconfiggenerator.sh latest
#echo "Building webhook_init_container..."
#./build-artifact.sh latest
#echo "Building resource cleaner..."
Expand All @@ -87,7 +87,7 @@ jobs:
docker images
echo "Installing KubePlus..."
helm install kubeplus ./deploy/kubeplus-chart --kubeconfig=kubeplus-saas-provider.json --set MUTATING_WEBHOOK=gcr.io/cloudark-kubeplus/pac-mutating-admission-webhook:latest --set PLATFORM_OPERATOR=gcr.io/cloudark-kubeplus/platform-operator:latest --set HELMER=gcr.io/cloudark-kubeplus/helm-pod:latest -n $KUBEPLUS_NS
helm install kubeplus ./deploy/kubeplus-chart --kubeconfig=kubeplus-saas-provider.json --set MUTATING_WEBHOOK=gcr.io/cloudark-kubeplus/pac-mutating-admission-webhook:latest --set PLATFORM_OPERATOR=gcr.io/cloudark-kubeplus/platform-operator:latest --set HELMER=gcr.io/cloudark-kubeplus/helm-pod:latest --set CRD_REGISTRATION_HELPER=gcr.io/cloudark-kubeplus/kubeconfiggenerator:latest -n $KUBEPLUS_NS
kubectl get pods -A
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ The KubePlus Operator does not need any admin-level permissions on a cluster for

### Resource utilization

KubePlus provides controls to set per-namespace resource quotas. It also monitors usage of CPU, memory, storage, and network traffic at the application instance level. The collected metrics are available in different formats and can be pulled into Prometheus for historical usage tracking.
KubePlus provides controls to set per-namespace resource quotas. It also monitors usage of CPU, memory, storage, and network traffic at the application instance level. The collected metrics are available in different formats and can be pulled into Prometheus for historical usage tracking. KubePlus also supports ability to define licenses for the CRDs. A license defines the number of application instances that can be created for that CRD, and an expiry date. KubePlus prevents creation of application instances if the license terms are not met.

### Upgrades

Expand All @@ -37,7 +37,8 @@ A new version of an application can be deployed by updating the application Helm

### Customization

The spec properties of the Kubernetes CRD wrapping the application Helm chart are the fields defined in the chart’s values.yaml file. Application deployments can be customized by specifying different values for these spec properties.
The spec properties of the Kubernetes CRD wrapping the application Helm chart are the fields defined in the chart’s values.yaml file. Application deployments can be customized by specifying different values for these spec properties.


## Demo

Expand Down Expand Up @@ -85,7 +86,7 @@ Let’s look at an example of creating a multi-instance WordPress Service using
5. Install KubePlus Operator using the generated provider kubeconfig

```
helm install kubeplus "https://github.com/cloud-ark/operatorcharts/blob/master/kubeplus-chart-3.0.44.tgz?raw=true" --kubeconfig=kubeplus-saas-provider.json -n $KUBEPLUS_NS
helm install kubeplus "https://github.com/cloud-ark/operatorcharts/blob/master/kubeplus-chart-3.0.46.tgz?raw=true" --kubeconfig=kubeplus-saas-provider.json -n $KUBEPLUS_NS
until kubectl get pods -A | grep kubeplus | grep Running; do echo "Waiting for KubePlus to start.."; sleep 1; done
```

Expand Down
61 changes: 61 additions & 0 deletions deploy/kubeconfiggenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import os
import yaml
import time
from datetime import date

from logging.config import dictConfig

Expand Down Expand Up @@ -1181,6 +1182,66 @@ def create_network_policy():
return err_string


@app.route("/checklicense")
def check_license():
app.logger.info("Inside checklicense..")
namespace = request.args.get("namespace").strip()
kind = request.args.get("kind").strip()
app.logger.info("Namespace:" + namespace + " kind:" + kind)
license_cfgmap = kind.lower() + "-license"
app.logger.info("License configmap:" + license_cfgmap)
cmd = "kubectl get configmap " + license_cfgmap + " -n " + namespace + " -o json "
out, err = run_command(cmd)
if "NotFound" in err:
app.logger.info(str(err))
app.logger.info("License not defined. No checks are needed.")
return ""

json_op = json.loads(out)
allowed_instances = ""
expiry = ""
if "allowed_instances" in json_op["metadata"]["annotations"]:
allowed_instances = json_op["metadata"]["annotations"]["allowed_instances"]
app.logger.info("Allowed instances:" + allowed_instances)
if "expiry" in json_op["metadata"]["annotations"]:
expiry = json_op["metadata"]["annotations"]["expiry"]
app.logger.info("Expiry:" + expiry)

msg = ""

if allowed_instances != "":
cmd1 = "kubectl get " + kind
out1, err1 = run_command(cmd1)
created_instances = 0
for line in out1.split("\n"):
line = line.strip()
app.logger.info("Line:" + line + "\n")
if "NAME" not in line and "AGE" not in line and line != "":
created_instances = created_instances + 1
app.logger.info("Already created instances:" + str(created_instances))

if created_instances >= int(allowed_instances):
msg = msg + "Allowed number of instances reached."

if expiry != "":
parts = expiry.split("/")
if len(parts) == 3 :
month = int(parts[0].strip())
day = int(parts[1].strip())
year = int(parts[2].strip())

expiry_date = date(year, month, day)
today = date.today()
app.logger.info("Expiry date:" + str(expiry_date))
app.logger.info("Today:" + str(today))
if today > expiry_date:
msg = msg + " License expired (expiry date):" + str(expiry) + "."

app.logger.info("License check message:" + msg)

return msg


@app.route("/resource_quota")
def create_resource_quota():
app.logger.info("Inside create_resource_quota..")
Expand Down
4 changes: 2 additions & 2 deletions deploy/kubeplus-chart/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 3.0.44
version: 3.0.46

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
appVersion: 28becf2817343d25a65590b3f2208e0424d867c5
appVersion: 39d1d59d97fc3ebee2a1bc1d0f09b2db7c9ae208

4 changes: 2 additions & 2 deletions deploy/kubeplus-chart/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ CHECK_KYVERNO_POLICIES: NO

# Containers
WEBHOOK_INIT_CONTAINER: gcr.io/cloudark-kubeplus/webhook-tls-getter:3.0.28
CRD_REGISTRATION_HELPER: gcr.io/cloudark-kubeplus/kubeconfiggenerator:3.0.28
MUTATING_WEBHOOK: gcr.io/cloudark-kubeplus/pac-mutating-admission-webhook:3.0.15
CRD_REGISTRATION_HELPER: gcr.io/cloudark-kubeplus/kubeconfiggenerator:3.0.29
MUTATING_WEBHOOK: gcr.io/cloudark-kubeplus/pac-mutating-admission-webhook:3.0.17
PLATFORM_OPERATOR: gcr.io/cloudark-kubeplus/platform-operator:3.0.7
CONSUMERUI: gcr.io/cloudark-kubeplus/consumerui:0.0.7
HELMER: gcr.io/cloudark-kubeplus/helm-pod:3.0.21
Expand Down
1 change: 1 addition & 0 deletions deploy/versions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@
3.0.26
3.0.27
3.0.28
3.0.29
2 changes: 1 addition & 1 deletion examples/multitenancy/application-hosting/odoo/steps.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ This example shows delivering Bitnami Odoo Helm chart as-a-service using KubePlu
$ python ../../../provider-kubeconfig.py create default -s $server
- Install KubePlus

$ helm install kubeplus "https://github.com/cloud-ark/operatorcharts/blob/master/kubeplus-chart-3.0.44.tgz?raw=true" --kubeconfig=kubeplus-saas-provider.json
$ helm install kubeplus "https://github.com/cloud-ark/operatorcharts/blob/master/kubeplus-chart-3.0.46.tgz?raw=true" --kubeconfig=kubeplus-saas-provider.json
- Wait till KubePlus Pod is Running
$ kubectl get pods -A

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ $ kubectl kubeplus commands
$ cd examples/multitenancy/wordpress/

4. Install KubePlus Operator:
$ helm install kubeplus "https://github.com/cloud-ark/operatorcharts/blob/master/kubeplus-chart-3.0.44.tgz?raw=true" -n $KUBEPLUS_NS --kubeconfig=kubeplus-saas-provider.json
$ helm install kubeplus "https://github.com/cloud-ark/operatorcharts/blob/master/kubeplus-chart-3.0.46.tgz?raw=true" -n $KUBEPLUS_NS --kubeconfig=kubeplus-saas-provider.json

5. Extract consumer kubeconfig:
$ kubectl retrieve kubeconfig consumer $KUBEPLUS_NS -s $apiserver > consumer.conf
Expand Down
3 changes: 1 addition & 2 deletions examples/multitenancy/hello-world/hs1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@ kind: HelloWorldService
metadata:
name: hs1
spec:
greeting: Hello hello hello
replicas: 1
greeting: Hello hello hello

3 changes: 2 additions & 1 deletion examples/multitenancy/hello-world/hs2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ kind: HelloWorldService
metadata:
name: hs2
spec:
greeting: Hello1 hello hello
greeting: Hello hello hello - hs2
replicas: 1

2 changes: 1 addition & 1 deletion examples/multitenancy/hello-world/steps.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ $ apiserver=`kubectl config view --minify -o jsonpath='{.clusters[0].cluster.ser
$ python3 provider-kubeconfig.py -s $apiserver create $KUBEPLUS_NS
$ cp kubeplus-saas-provider.json examples/multitenancy/hello-world/provider.conf
$ cd examples/multitenancy/hello-world/
$ helm install kubeplus "https://github.com/cloud-ark/operatorcharts/blob/master/kubeplus-chart-3.0.44.tgz?raw=true" -n $KUBEPLUS_NS --kubeconfig=provider.conf
$ helm install kubeplus "https://github.com/cloud-ark/operatorcharts/blob/master/kubeplus-chart-3.0.46.tgz?raw=true" -n $KUBEPLUS_NS --kubeconfig=provider.conf
$ kubectl get pods (wait till kubeplus pod is Running)


Expand Down
2 changes: 1 addition & 1 deletion examples/multitenancy/managed-service/appday2ops/steps.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Install KubePlus:
$ KUBEPLUS_NS=default
$ python ../../../provider-kubeconfig.py create $KUBEPLUS_NS
$ cp kubeplus-saas-provider.json provider.conf
$ helm install kubeplus "https://github.com/cloud-ark/operatorcharts/blob/master/kubeplus-chart-3.0.44.tgz?raw=true" -n $KUBEPLUS_NS --kubeconfig=provider.conf
$ helm install kubeplus "https://github.com/cloud-ark/operatorcharts/blob/master/kubeplus-chart-3.0.46.tgz?raw=true" -n $KUBEPLUS_NS --kubeconfig=provider.conf
$ until kubectl get pods -A | grep kubeplus | grep Running; do echo "Waiting for KubePlus to start.."; sleep 1; done


Expand Down
2 changes: 1 addition & 1 deletion examples/multitenancy/platform-engineering/steps.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Platform Engineering team
$ python ../../../provider-kubeconfig.py create default -s $server
- Install KubePlus

$ helm install kubeplus "https://github.com/cloud-ark/operatorcharts/blob/master/kubeplus-chart-3.0.44.tgz?raw=true" --kubeconfig=kubeplus-saas-provider.json
$ helm install kubeplus "https://github.com/cloud-ark/operatorcharts/blob/master/kubeplus-chart-3.0.46.tgz?raw=true" --kubeconfig=kubeplus-saas-provider.json
- Wait till KubePlus Pod is Running
$ kubectl get pods -A

Expand Down
53 changes: 32 additions & 21 deletions mutating-webhook/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -814,10 +814,10 @@ func GetPlural(kind, group string) []byte {
}

func CheckResource(kind, plural string) []byte {
fmt.Printf("Inside CheckResource...\n")
//fmt.Printf("Inside CheckResource...\n")
args := fmt.Sprintf("kind=%s&plural=%s", kind, plural)
url1 := fmt.Sprintf("http://%s:%s/apis/kubeplus/checkResource?%s", serviceHost, servicePort, args)
fmt.Printf("Url:%s\n", url1)
//fmt.Printf("Url:%s\n", url1)
body := queryKubeDiscoveryService(url1)
return body
}
Expand Down Expand Up @@ -862,14 +862,25 @@ func QueryDeployEndpoint(platformworkflow, customresource, namespace, overrides,
CreateOverrides(platformworkflow, customresource)

args := fmt.Sprintf("platformworkflow=%s&customresource=%s&namespace=%s&overrides=%s&cpu_req=%s&cpu_lim=%s&mem_req=%s&mem_lim=%s&labels=%s", platformworkflow, customresource, namespace, encodedOverrides, cpu_req, cpu_lim, mem_req, mem_lim,labels)
fmt.Printf("Inside QueryDeployEndpoint...\n")
//fmt.Printf("Inside QueryDeployEndpoint...\n")
var url1 string
url1 = fmt.Sprintf("http://%s:%s/apis/kubeplus/deploy?%s", serviceHost, servicePort, args)
fmt.Printf("Url:%s\n", url1)
//fmt.Printf("Url:%s\n", url1)
body := queryKubeDiscoveryService(url1)
return body
}

func CheckLicense(kind, webhook_namespace string) string {
//fmt.Printf("Inside CheckLicense...\n")
args := fmt.Sprintf("kind=%s&namespace=%s", kind, webhook_namespace)
var url1 string
url1 = fmt.Sprintf("http://%s:%s/checklicense?%s", serviceHost, verificationServicePort, args)
//fmt.Printf("Url:%s\n", url1)
body := queryKubeDiscoveryService(url1)
bodyString := string(body)
return bodyString
}

func DryRunChart(platformworkflow, namespace string) []byte {
args := fmt.Sprintf("platformworkflow=%s&namespace=%s&dryrun=true", platformworkflow, namespace)
fmt.Printf("Inside DryRunChart...\n")
Expand All @@ -892,25 +903,25 @@ func TestChartDeployment(kind, namespace, chartName, chartURL string) []byte {
}

func CreateOverrides(platformworkflow, customresource string) []byte {
fmt.Printf("Inside CreateOverrides...\n")
//fmt.Printf("Inside CreateOverrides...\n")
args := fmt.Sprintf("platformworkflow=%s&customresource=%s", platformworkflow, customresource)
var url1 string
url1 = fmt.Sprintf("http://%s:%s/overrides?%s", serviceHost, verificationServicePort, args)
fmt.Printf("Url:%s\n", url1)
//fmt.Printf("Url:%s\n", url1)
body := queryKubeDiscoveryService(url1)
return body
}

func CheckClusterCapacity(cpuRequests, cpuLimits, memRequests, memLimits string) (bool, string) {
fmt.Printf("Inside CheckClusterCapacity...\n")
//fmt.Printf("Inside CheckClusterCapacity...\n")
var url1 string
url1 = fmt.Sprintf("http://%s:%s/cluster_capacity", serviceHost, verificationServicePort)
fmt.Printf("Url:%s\n", url1)
//fmt.Printf("Url:%s\n", url1)
body := queryKubeDiscoveryService(url1)

var clusterCapacity ClusterCapacity
json.Unmarshal(body, &clusterCapacity)
fmt.Printf("Cluster Capacity:%v\n", clusterCapacity)
//fmt.Printf("Cluster Capacity:%v\n", clusterCapacity)

bodyString := string(body)
//jsonresp := bodyString.(map[string]string)
Expand All @@ -926,9 +937,9 @@ func CheckClusterCapacity(cpuRequests, cpuLimits, memRequests, memLimits string)
memParts := strings.Split(parts[1],":")
totalAllocatableMemoryGB, _ := strconv.ParseFloat(strings.TrimSpace(memParts[1]), 64)

fmt.Printf("Total Allocatable CPU:%d\n", totalAllocatableCPU)
/*fmt.Printf("Total Allocatable CPU:%d\n", totalAllocatableCPU)
fmt.Printf("Total Allocatable Memory:%f\n", totalAllocatableMemoryGB)

*/
cpuRequestsI, _ := strconv.Atoi(strings.TrimSpace(strings.ReplaceAll(cpuRequests, "m", "")))
cpuLimitsI, _ := strconv.Atoi(strings.TrimSpace(strings.ReplaceAll(cpuLimits, "m", "")))

Expand Down Expand Up @@ -962,23 +973,23 @@ func GetExistingResourceCompositions() []byte {
}

func CheckChartExists(chartURL string) []byte {
fmt.Printf("Inside CheckChartExists...\n")
//fmt.Printf("Inside CheckChartExists...\n")
encodedChartURL := url.QueryEscape(chartURL)
args := fmt.Sprintf("chartURL=%s", encodedChartURL)
var url1 string
url1 = fmt.Sprintf("http://%s:%s/checkchartexists?%s", serviceHost, verificationServicePort, args)
fmt.Printf("Url:%s\n", url1)
//fmt.Printf("Url:%s\n", url1)
body := queryKubeDiscoveryService(url1)
return body
}

func LintChart(chartURL string) []byte {
fmt.Printf("Inside LintChart...\n")
//fmt.Printf("Inside LintChart...\n")
encodedChartURL := url.QueryEscape(chartURL)
args := fmt.Sprintf("chartURL=%s", encodedChartURL)
var url1 string
url1 = fmt.Sprintf("http://%s:%s/dryrunchart?%s", serviceHost, verificationServicePort, args)
fmt.Printf("Url:%s\n", url1)
//fmt.Printf("Url:%s\n", url1)
body := queryKubeDiscoveryService(url1)
return body
}
Expand Down Expand Up @@ -1015,10 +1026,10 @@ func QueryCompositionEndpoint(kind, namespace, crdKindName string) []byte {

func GetValuesYaml(platformworkflow, namespace string) []byte {
args := fmt.Sprintf("platformworkflow=%s&namespace=%s", platformworkflow, namespace)
fmt.Printf("Inside GetValuesYaml...\n")
//fmt.Printf("Inside GetValuesYaml...\n")
var url1 string
url1 = fmt.Sprintf("http://%s:%s/apis/kubeplus/getchartvalues?%s", serviceHost, servicePort, args)
fmt.Printf("Url:%s\n", url1)
//fmt.Printf("Url:%s\n", url1)
body := queryKubeDiscoveryService(url1)
return body
}
Expand Down Expand Up @@ -1052,7 +1063,7 @@ func getServiceEndpoint(servicename string) (string, string) {

// Rename this function to a more generic name since we use it to trigger Custom Resource deployment as well.
func queryKubeDiscoveryService(url1 string) []byte {
fmt.Printf("..inside queryKubeDiscoveryService")
//fmt.Printf("..inside queryKubeDiscoveryService")
u, err := url.Parse(url1)
//fmt.Printf("URL:%s\n",u)
if err != nil {
Expand All @@ -1074,9 +1085,9 @@ func queryKubeDiscoveryService(url1 string) []byte {
defer resp.Body.Close()
resp_body, _ := ioutil.ReadAll(resp.Body)

fmt.Println("Response status:%s\n",resp.Status)
fmt.Println("Response body:%s\n",string(resp_body))
fmt.Println("Exiting queryKubeDiscoveryService")
//fmt.Println("Response status:%s\n",resp.Status)
//fmt.Println("Response body:%s\n",string(resp_body))
//fmt.Println("Exiting queryKubeDiscoveryService")
return resp_body
}

Expand Down
2 changes: 2 additions & 0 deletions mutating-webhook/versions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@
3.0.13
3.0.14
3.0.15
3.0.16
3.0.17
Loading

0 comments on commit 9ed594c

Please sign in to comment.