Skip to content

Commit

Permalink
Merge pull request #25 from IBM/issue13
Browse files Browse the repository at this point in the history
Use Kubernetes API Instead of Calling Kubectl Through the Subproccess Module
  • Loading branch information
dpeace8 committed Aug 3, 2021
2 parents 3a2a6bc + 65e6445 commit f82f13f
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 87 deletions.
2 changes: 2 additions & 0 deletions src/common/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class IntegrationInfo:
cert_name= ''
cis_domain = ''
schematics_url = 'https://us.schematics.cloud.ibm.com'
iks_master_url = ''
terraforming = False
verbose = False
delete = False
Expand Down Expand Up @@ -143,6 +144,7 @@ def get_iks_info(self):

data=json.loads(response.text)
self.app_url=data["ingress"]["hostname"]
self.iks_master_url=data["serviceEndpoints"]["publicServiceEndpointURL"]
return data
except:
print(Color.RED+"ERROR: Unable to get cluster's data"+Color.END)
Expand Down
139 changes: 69 additions & 70 deletions src/iks/create_ingress.py
Original file line number Diff line number Diff line change
@@ -1,91 +1,90 @@
import requests
import os
import subprocess
import json
from src.common.functions import Color as Color

class IngressCreator:
def __init__(self, clusterNameOrID, resourceGroupID, namespace, secretName, serviceName, servicePort, accessToken, refreshToken, ingressSubdomain ):
def __init__(self, clusterNameOrID, resourceGroupID, namespace, secretName, serviceName, servicePort, accessToken, refreshToken, ingressSubdomain, iks_master_url):
self.clusterNameOrID=clusterNameOrID
self.resourceGroupID=resourceGroupID
self.namespace=namespace
self.secretName=secretName
self.serviceName=serviceName
self.servicePort=servicePort
self.accessToken= accessToken
self.accessToken=accessToken
self.refreshToken=refreshToken
self.ingressSubdomain=ingressSubdomain

def getKubeConfig(self):

url = "https://containers.cloud.ibm.com/global/v2/getKubeconfig?cluster="+self.clusterNameOrID

payload = ""
headers = {
'X-Auth-Resource-Group': self.resourceGroupID,
'X-Auth-Refresh-Token': self.refreshToken,
'Authorization': self.accessToken,
'accept': 'application/json'
}
try:
response = requests.request("GET", url, headers=headers, data=payload)
text_file = open("config.txt", "w")
n = text_file.write(response.text)
text_file.close()
os.environ['KUBECONFIG'] = "config.txt"
print(Color.GREEN+"SUCCESS: Installed kube config file"+Color.END)

except:
print(Color.RED+"ERROR: Unable to Install kube config file"+Color.END)
self.iks_master_url=iks_master_url

def create_ingress(self):
if self.iks_master_url =="":
print(Color.RED+"ERROR: Public service endpoint for IKS Cluster is not enabled"+Color.END)
#1. get id token to make kubernetes API calls
url = "https://iam.cloud.ibm.com/identity/token"

#1. setting config
self.getKubeConfig()
payload="grant_type=urn%3Aibm%3Aparams%3Aoauth%3Agrant-type%3Aapikey&apikey="+os.getenv("CIS_SERVICES_APIKEY")
headers = {
'content-type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic a3ViZTprdWJl',
'cache-control': 'no-cache'
}
try:
response = requests.request("POST", url, headers=headers, data=payload)
data=json.loads(response.text)
idToken=data["id_token"]
except:
print(Color.RED+"ERROR: Unable to get id token"+Color.END)

#2. getting ingressSubdomain
ingressFileName="ingress.yaml"



#2. apply yaml file through kubernetes API
url = self.iks_master_url+"/apis/networking.k8s.io/v1beta1/namespaces/"+self.namespace+"/ingresses"
payload = json.dumps({
"apiVersion": "networking.k8s.io/v1beta1",
"kind": "Ingress",
"metadata": {
"name": "cis-cert",
"annotations": {
"nginx.ingress.kubernetes.io/ssl-redirect": "false"
}
},
"spec": {
"tls": [
{
"hosts": [
self.ingressSubdomain
],
"secretName": self.secretName
}
],
"rules": [
{
"host": self.ingressSubdomain,
"http": {
"paths": [
{
"path": "/",
"backend": {
"serviceName": self.serviceName,
"servicePort": int(self.servicePort)
}
}
]
}
}
]
}
})
headers = {
'Authorization': 'bearer'+' '+idToken,
'Content-Type': 'application/json'
}
try:
response = requests.request("POST", url, headers=headers, data=payload, verify=False)
print(Color.GREEN+"SUCCESS: Created ingress file"+Color.END)

yaml='''apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: cis-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
tls:
- hosts:
- '''+self.ingressSubdomain+'''
secretName: '''+self.secretName+'''
rules:
- host: '''+self.ingressSubdomain+'''
http:
paths:
- path: /
backend:
serviceName: '''+self.serviceName+'''
servicePort: '''+self.servicePort
except:
print(Color.RED+"ERROR: Unable to create ingress file"+Color.END)

#3. create yaml file
text_file = open(ingressFileName, "w")
n = text_file.write(yaml)
text_file.close()

#4. kubectl sanity check
try:
subprocess.check_output(["kubectl", "--help"], stderr=subprocess.STDOUT)
except:
print(Color.RED+"ERROR: Kubectl is not installed"+Color.END)

#5. apply yaml
try:

subprocess.check_output(["kubectl", "apply", "-f", ingressFileName, "--namespace="+self.namespace], stderr=subprocess.STDOUT)
print(Color.GREEN+"SUCCESS: Ingress was created"+Color.END)

except subprocess.CalledProcessError as e:
print(Color.RED+"ERROR: Ingress was not created"+Color.END)
#6 delete ingress yaml and kube config file
os.remove(ingressFileName)
os.remove("config.txt")
#future enchancements: use kubectl api
39 changes: 22 additions & 17 deletions src/iks/iks.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ def print_help():


def handle_args(args):

if args.help:
print_help()
sys.exit(1)

UserInfo = IntegrationInfo()
UserInfo.terraforming = False
if args.terraform:
Expand All @@ -36,28 +37,28 @@ def handle_args(args):

if args.delete:
UserInfo.delete = True

# determining API key
UserInfo.cis_api_key = getpass.getpass(
prompt="Enter CIS Services API Key: ")
os.environ["CIS_SERVICES_APIKEY"] = UserInfo.cis_api_key

# common arguments
UserInfo.request_token()

if not UserInfo.delete:
UserInfo.iks_cluster_id = args.iks_cluster_id
if UserInfo.iks_cluster_id is None:
print("You did not specify an IKS cluster ID.")
sys.exit(1)

iks_info = UserInfo.get_iks_info()

UserInfo.cis_domain = args.cis_domain
if UserInfo.cis_domain is None:
print("You did not specify a CIS Domain.")
sys.exit(1)

# terraforming vs. not terraforming
if UserInfo.terraforming and not UserInfo.delete:
UserInfo.resource_group = args.resource_group
Expand All @@ -73,8 +74,7 @@ def handle_args(args):
sys.exit(1)

if not UserInfo.get_crn_and_zone():
print(
"Failed to retrieve CRN and Zone ID. Check the name of your CIS instance and try again")
print("Failed to retrieve CRN and Zone ID. Check the name of your CIS instance and try again")
sys.exit(1)

else:
Expand Down Expand Up @@ -112,19 +112,18 @@ def handle_args(args):
UserInfo.cis_name = args.name

if UserInfo.cis_name is None:
print(
"Please specify the name of your CIS instance or both the CIS CRN and CIS Zone ID")
print("Please specify the name of your CIS instance or both the CIS CRN and CIS Zone ID")
sys.exit(1)

if not UserInfo.get_crn_and_zone():
print(
"Failed to retrieve CRN and Zone ID. Check the name of your CIS instance and try again")
print("Failed to retrieve CRN and Zone ID. Check the name of your CIS instance and try again")
sys.exit(1)

return UserInfo


def iks(args):

UserInfo = handle_args(args)
if UserInfo.delete and not UserInfo.terraforming:
delete_dns = DeleteDNS(UserInfo.crn, UserInfo.zone_id, UserInfo.api_endpoint, UserInfo.cis_domain)
Expand All @@ -143,8 +142,10 @@ def iks(args):
UserInfo.verbose, UserInfo.token)
work_creator.create_terraform_workspace()
else:

# handle the case of using python
# 1. Domain Name and DNS
'''
user_DNS = DNSCreator(UserInfo.crn, UserInfo.zone_id,
UserInfo.api_endpoint, UserInfo.app_url)
Expand All @@ -156,10 +157,11 @@ def iks(args):
resource_group_id = UserInfo.get_resource_id()
user_ACL = AclRuleCreator(resource_group_id, UserInfo.vpc_name, UserInfo.cis_api_key)
user_ACL.check_network_acl()

'''
# 2. Generate certificate in manager if necessary
UserInfo.cert_name="cis-cert"

UserInfo.cert_name="cis-cert"
'''
cms_id = UserInfo.get_cms()
# print("\n"+cms_id)
user_cert = SecretCertificateCreator(
Expand All @@ -174,8 +176,9 @@ def iks(args):
user_cert.create_secret()

'''
#3 generate ingress

UserInfo.secret_name=UserInfo.cert_name
user_ingress = IngressCreator(
clusterNameOrID=UserInfo.iks_cluster_id,
Expand All @@ -186,11 +189,13 @@ def iks(args):
servicePort=UserInfo.service_port,
accessToken=UserInfo.token["access_token"],
refreshToken=UserInfo.token["refresh_token"],
ingressSubdomain=UserInfo.app_url
ingressSubdomain=UserInfo.app_url,
iks_master_url=UserInfo.iks_master_url
)
user_ingress.create_ingress()



if not UserInfo.delete:
hostUrl = "https://"+UserInfo.cis_domain

Expand Down

0 comments on commit f82f13f

Please sign in to comment.