@@ -21,6 +21,7 @@ package jobs
2121import (
2222 "bytes"
2323 "context"
24+ "encoding/base64"
2425 "encoding/json"
2526 "fmt"
2627 "path/filepath"
@@ -30,6 +31,7 @@ import (
3031
3132 "github.com/nginxinc/nginx-k8s-supportpkg/pkg/crds"
3233 "github.com/nginxinc/nginx-k8s-supportpkg/pkg/data_collector"
34+ v1 "k8s.io/api/core/v1"
3335 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3436)
3537
@@ -54,8 +56,113 @@ func ParseNginxIngressProductInfo(res []byte) data_collector.ProductInfo {
5456 return productInfo
5557}
5658
59+ // Returns the first found pod with the 'ingress' substring in its name
60+ func getNginxIngressPod (dc * data_collector.DataCollector , ctx context.Context ) (v1.Pod , error ) {
61+ for _ , namespace := range dc .Namespaces {
62+ pods , err := dc .K8sCoreClientSet .CoreV1 ().Pods (namespace ).List (ctx , metav1.ListOptions {})
63+ if err != nil {
64+ dc .Logger .Printf ("\t Could not retrieve pod list for namespace %s: %v\n " , namespace , err )
65+ } else {
66+ for _ , pod := range pods .Items {
67+ if strings .Contains (pod .Name , "ingress" ) {
68+ return pod , nil
69+ }
70+ }
71+ }
72+ }
73+ return v1.Pod {}, fmt .Errorf ("no nginx-ingress pod found in the provided namespaces" )
74+ }
75+
5776func NICJobList () []Job {
5877 jobList := []Job {
78+ {
79+ Name : "parse-entitlement" ,
80+ Timeout : time .Second * 10 ,
81+ Execute : func (dc * data_collector.DataCollector , ctx context.Context , ch chan JobResult ) {
82+ jobResult := JobResult {Files : make (map [string ][]byte ), Error : nil }
83+
84+ ingressPod , err := getNginxIngressPod (dc , ctx )
85+ if err != nil {
86+ dc .Logger .Printf ("\t Could not find nginx-ingress pod: %v\n " , err )
87+ jobResult .Error = err
88+ ch <- jobResult
89+ return
90+ }
91+
92+ for _ , container := range ingressPod .Spec .Containers {
93+ if container .Name == "nginx-ingress" {
94+ for _ , arg := range container .Args {
95+ if strings .Contains (arg , "mgmt-configmap" ) {
96+ configMapString := strings .SplitN (arg , "=" , 2 )
97+ if len (configMapString ) != 2 {
98+ dc .Logger .Printf ("\t Could not parse mgmt-configmap argument: %s\n " , arg )
99+ jobResult .Error = fmt .Errorf ("could not parse mgmt-configmap argument: %s" , arg )
100+ ch <- jobResult
101+ return
102+ }
103+ configMapName := strings .Split (configMapString [1 ], "/" )[1 ]
104+ configMapNamespace := strings .Replace (strings .Split (configMapString [1 ], "/" )[0 ], "$(POD_NAMESPACE)" , ingressPod .Namespace , 1 )
105+
106+ configMap , err := dc .K8sCoreClientSet .CoreV1 ().ConfigMaps (configMapNamespace ).Get (ctx , configMapName , metav1.GetOptions {})
107+ if err != nil {
108+ dc .Logger .Printf ("\t Could not retrieve ConfigMap %s in namespace %s: %v\n " , configMapName , configMapNamespace , err )
109+ jobResult .Error = err
110+ ch <- jobResult
111+ return
112+ }
113+
114+ licenseTokenSecretName , exists := configMap .Data ["license-token-secret-name" ]
115+ if ! exists {
116+ dc .Logger .Printf ("\t ConfigMap %s in namespace %s does not contain 'license-token-secret-name' key\n " , configMapName , configMapNamespace )
117+ jobResult .Error = fmt .Errorf ("configmap %s in namespace %s does not contain 'license-token-secret-name' key" , configMapName , configMapNamespace )
118+ ch <- jobResult
119+ return
120+ }
121+
122+ licenseTokenSecret , err := dc .K8sCoreClientSet .CoreV1 ().Secrets (configMapNamespace ).Get (ctx , licenseTokenSecretName , metav1.GetOptions {})
123+ if err != nil {
124+ dc .Logger .Printf ("\t Could not retrieve Secret %s in namespace %s: %v\n " , licenseTokenSecretName , configMapNamespace , err )
125+ jobResult .Error = err
126+ ch <- jobResult
127+ return
128+ }
129+
130+ licenseToken , exists := licenseTokenSecret .Data ["license.jwt" ]
131+ if ! exists {
132+ dc .Logger .Printf ("\t Secret %s in namespace %s does not contain 'license.jwt' key\n " , licenseTokenSecretName , configMapNamespace )
133+ jobResult .Error = fmt .Errorf ("secret %s in namespace %s does not contain 'license.jwt' key" , licenseTokenSecretName , configMapNamespace )
134+ ch <- jobResult
135+ return
136+ }
137+
138+ claim := strings .Split (string (licenseToken ), "." )[1 ]
139+ decodedClaim , err := base64 .RawStdEncoding .DecodeString (claim )
140+ if err != nil {
141+ dc .Logger .Printf ("\t Could not decode license token claim from Secret %s in namespace %s: %v\n " , licenseTokenSecretName , configMapNamespace , err )
142+ jobResult .Error = err
143+ ch <- jobResult
144+ return
145+ }
146+
147+ var prettyJSON bytes.Buffer
148+ err = json .Indent (& prettyJSON , decodedClaim , "" , " " )
149+ if err != nil {
150+ dc .Logger .Printf ("\t Could not format license token claim JSON from Secret %s in namespace %s: %v\n " , licenseTokenSecretName , configMapNamespace , err )
151+ jobResult .Error = err
152+ ch <- jobResult
153+ return
154+ }
155+
156+ fileName := fmt .Sprintf ("%s_payload.json" , licenseTokenSecretName )
157+ jobResult .Files [filepath .Join (dc .BaseDir , "entitlement" , ingressPod .Namespace , fileName )] = prettyJSON .Bytes ()
158+ break
159+ }
160+ }
161+ }
162+ }
163+ ch <- jobResult
164+ },
165+ },
59166 {
60167 Name : "exec-nginx-ingress-version" ,
61168 Timeout : time .Second * 10 ,
0 commit comments