-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathkubectl-log2rbac
executable file
·130 lines (121 loc) · 7.51 KB
/
kubectl-log2rbac
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/bin/bash
export CR_TEMPLATE=$(cat <<CustomResource
apiVersion: kremser.dev/v1
kind: RbacNegotiation
metadata:
name: for-\$resource
spec:
for:
kind: \$kind
name: \$resource
namespace: \$ns
role:
name: new-\$resource-role
isClusterRole: true
createIfNotExist: true
CustomResource
)
LOG2RBAC_COMMON_FZF_ARGS="--ansi --cycle --height=45% --margin=2 --layout=reverse --info=inline --margin=2 --layout=reverse --info=inline"
LOG2RBAC_FZF_ARGS="$LOG2RBAC_COMMON_FZF_ARGS --preview-window right:80% --color preview-bg:#333333"
_OPT1_DESC="Initiates the rbac negotiation for one of the supported Kubernetes kinds.;This will then create the custom resource for the operator to start the RBAC negotiation.;You will be asked in the next step for more details"
_OPT2_DESC="log2rbac operator related tasks. You can deploy and undeploy the operator using this option."
createCr() {
[[ $# != 3 ]] && echo "Wrong number of arguments, usage: createCr <ns> <kind> <resource>" && exit 2
ns=$1; kind=$2; resource=$3
OLD_IFS="$IFS" && IFS=""
[[ ! -z $resource ]] && echo $CR_TEMPLATE | resource=$resource ns=$ns kind=$kind envsubst | kubectl apply -f -
IFS="$OLD_IFS"
}
mainMenu() {
_KUBECTL_CONTEXT=$(kubectl config current-context)
which figlet > /dev/null && figlet log2rbac
ans1=`echo -e "Negotiate RBAC\t$_OPT1_DESC\nOperator management\t$_OPT2_DESC" | nl -v0 | fzf --header "Select an action to do" --prompt='log2rbac λ' --preview="echo {} | cut -d$'\t' -f 3- | tr ';' '\n'" --with-nth=2 -d "\\t" ${LOG2RBAC_FZF_ARGS} | awk '{print $1}'`
[[ $ans1 == 0 ]] && {
# Negotiate RBAC
ns=`kubectl get ns --no-headers | fzf -e $LOG2RBAC_COMMON_FZF_ARGS --header "Select the k8s namespace with the resource for which you want to start the rbac negotiation" | cut -d' ' -f1`
[[ -z $ns ]] && exit 0
kindAnswer=`echo -e "Deployment\nReplicaSet\nDaemonSet\nStatefulSet\nService\nCustom pod selector" | nl -v0 | fzf -e $LOG2RBAC_COMMON_FZF_ARGS --header "Select the Kind of the resource" --with-nth=2..`
[[ -z $kindAnswer ]] && exit 0
[[ $(echo $kindAnswer | awk '{print $1}') = 5 ]] && {
# custom pod selector
echo -e "\nWe support only one pair that identifies the pod using the labels on it (key=value).\nEnter the key:" && read key
echo "Enter the value:" && read value
echo -e "\n\nApplying following manifest:"
OLD_IFS="$IFS" && IFS=""
echo $CR_TEMPLATE | resource="$key-$value" ns=$ns kind="" envsubst | sed '5,10s/kind/podSelector/' | sed "/podSelector/a \ \ \ \ \ \ $key: $value" | tee /dev/tty | kubectl apply -f -
IFS="$OLD_IFS"
} || {
kind=$(echo $kindAnswer | awk '{print $2}')
_OPT1_DESC="Deploys the operator using the current kubectl context ($_KUBECTL_CONTEXT).;It will run the following command: kubectl apply -f http://bit.do/log2rbac;If you want to explore what is going to be deployed, check the url.;It contains all-in-one yaml with all the operator's components.;;;TLDR: runs kubectl apply -f http://bit.do/log2rbac"
resource=`kubectl get $kind -n $ns --no-headers | fzf --header "Select the $kind" --prompt='log2rbac λ' --preview='echo -e "Following custom resource will be created:\n" && echo -e \$CR_TEMPLATE | resource={1} ns='$ns' kind='$kind' envsubst' ${LOG2RBAC_FZF_ARGS} --preview-window right:65% | awk '{print $1}'`
createCr $ns $kind $resource
}
}
[[ $ans1 == 1 ]] && {
# Operator management
_OPT2_1_DESC="Deploys the operator using the current kubectl context ($_KUBECTL_CONTEXT).;It will run the following command: kubectl apply -f http://bit.do/log2rbac;If you want to explore what is going to be deployed, check the url.;It contains all-in-one yaml with all the operator's components.;;;TLDR: runs kubectl apply -f http://bit.do/log2rbac"
_OPT2_2_DESC="Undeploys all the operator's resources from the currently active kubectl context ($_KUBECTL_CONTEXT).;This is an inverse operation to the deploy and you will lose the oprator this way.;It doesn't clean the custom resources that have been created.;;;;TLDR: runs kubectl delete -f http://bit.do/log2rbac"
_OPT2_3_DESC="Prints the logs from the operator pod.;;;;;The following command will be run:;kubectl logs -f -lid=log2rbac -n log2rbac"
ans2=`echo -e "Deploy\t$_OPT2_1_DESC\nUndeploy\t$_OPT2_2_DESC\nPrint Logs\t$_OPT2_3_DESC" | nl -v0 | fzf --header "Select an action to do" --prompt='log2rbac λ' --preview="echo {} | cut -d$'\t' -f 3- | tr ';' '\n'" --with-nth=2 -d "\\t" ${LOG2RBAC_FZF_ARGS} | awk '{print $1}'`
[[ $ans2 == 0 ]] && {
echo -e "\nDeploying the operator.."
kubectl apply -f http://bit.do/log2rbac && echo -e "\nOperator was successfuly deployed!"
}
[[ $ans2 == 1 ]] && {
echo -e "\nUndeploying the operator.."
kubectl delete -f http://bit.do/log2rbac && echo -e "\nOperator was successfuly undeployed!"
}
[[ $ans2 == 2 ]] && {
echo -e "\nLogs:\n\n"
kubectl logs -f -lid=log2rbac -n log2rbac
}
}
}
printHelp() {
echo
echo "Usage:"
echo " kubectl log2rbac [args]"
echo
echo "Available args:"
echo " -h, --help Prints the help about the plugin (this output)"
echo " -v, --version Prints the help about the plugin (this output)"
echo " -n <ns> <kind> <resourceName> Creates the CR for operator and initiates the RBAC negotiation process"
echo " - <ns> is a valid k8s namespace that is available in the current context"
echo " - <kind> is one of the following: deployment, replicaset, statefulset, daemonset, service"
echo " - <resourceName> is the name of particular <kind> in namespace <ns>"
echo
echo "Examples:"
echo " kubectl log2rbac ... starts the plugin in the TUI (interactive) mode"
echo " kubectl log2rbac -n monitoring deployment prometheus ... creates the RbacNegotiation for the selected deployment"
echo " kubectl log2rbac -n default service my-service ... creates the RbacNegotiation for the service 'my-service'"
echo " kubectl log2rbac --namespace foo ss my-statefulset ... creates the RbacNegotiation for a stateful set in namespace foo"
echo
}
printVersion() {
[ "$(uname)" == "Darwin" ] && {
cat $(dirname `readlink $0`)/VERSION
} || {
cat $(dirname `readlink -f $0`)/VERSION
}
}
[[ $# == 0 ]] && {
! which fzf > /dev/null && echo "Install fzf, this plugin needs it" && exit 1
! which kubectl > /dev/null && echo "Install kubectl, this plugin needs it" && exit 2
mainMenu
exit 0
}
for param in "$@"; do
[[ $resNext == "2" ]] && echo "too many arguments" && printHelp && exit 1
([ $param == "-h" ] || [ $param == "--help" ]) && printHelp && exit 1
([ $param == "-v" ] || [ $param == "--version" ]) && printVersion && exit 1
[[ $nsNext == "1" ]] && ns=$param && nsNext=0 && continue
[[ $resNext == "1" ]] && res=$param && resNext=2 && continue
([ $param == "-n" ] || [ $param == "--namespace" ]) && nsNext=1 && continue
kind=$param && resNext=1
done
([ -z $ns ] || [ -z $kind ] || [ -z $res ]) && echo "not enough arguments" && printHelp && exit 1
[[ "$kind" =~ ^(deployment|deploy|replicaset|rs|statefulset|ss|daemonset|ds|service|svc)$ ]] || {
echo "Unsupported kind: $kind" && printHelp && exit 3
}
# do the thing
createCr "$ns" "$kind" "$res"