@@ -17,42 +17,23 @@ limitations under the License.
1717package debug
1818
1919import (
20- "bytes"
2120 "context"
2221 "fmt"
2322 "log"
2423 "os"
2524 "path"
26- "strings"
2725
2826 gitops "kubedb.dev/apimachinery/apis/gitops/v1alpha1"
29- dbapi "kubedb.dev/apimachinery/apis/kubedb/v1"
3027 opsapi "kubedb.dev/apimachinery/apis/ops/v1alpha1"
31- kubedbscheme "kubedb.dev/apimachinery/client/clientset/versioned/scheme"
3228
33- "github.com/spf13/cobra"
34- corev1 "k8s.io/api/core/v1"
35- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3629 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
3730 "k8s.io/apimachinery/pkg/runtime"
31+ "k8s.io/apimachinery/pkg/runtime/schema"
3832 "k8s.io/apimachinery/pkg/types"
39- utilruntime "k8s.io/apimachinery/pkg/util/runtime"
40- "k8s.io/client-go/discovery"
41- "k8s.io/client-go/kubernetes"
42- clientgoscheme "k8s.io/client-go/kubernetes/scheme"
4333 _ "k8s.io/client-go/plugin/pkg/client/auth"
44- "k8s.io/client-go/rest"
45- cmdutil "k8s.io/kubectl/pkg/cmd/util"
4634 "sigs.k8s.io/controller-runtime/pkg/client"
4735)
4836
49- var scheme = runtime .NewScheme ()
50-
51- func init () {
52- utilruntime .Must (clientgoscheme .AddToScheme (scheme ))
53- utilruntime .Must (kubedbscheme .AddToScheme (scheme ))
54- }
55-
5637type GitOpsStatus struct {
5738 GitOps gitops.GitOpsStatus `json:"gitops,omitempty" yaml:"gitops,omitempty"`
5839}
@@ -66,118 +47,58 @@ type Ops struct {
6647}
6748
6849type dbInfo struct {
69- resource string
50+ kind string
7051 name string
7152 namespace string
7253}
7354
7455type gitOpsOpts struct {
75- kc client.Client
76- config * rest.Config
77- db dbInfo
78- kubeClient kubernetes.Interface
56+ kc client.Client
57+ db dbInfo
7958
80- operatorNamespace string
81- dir string
82- errWriter * bytes.Buffer
83- resMap map [string ]string
84- summary []string
59+ dir string
60+ summary []string
8561}
8662
87- func GitOpsDebugCMD (f cmdutil.Factory ) * cobra.Command {
88- var dbName string
89- opts := newGitOpsOpts (f )
90- gitOpsDebugCmd := & cobra.Command {
91- Use : "gitops" ,
92- Aliases : []string {
93- "git" ,
94- },
95- Short : "Debug helper for gitops databases" ,
96- Example : `kubectl dba debug gitops --db-type mysql -n demo sample-mysql --operator-namespace kubedb` ,
97- Run : func (cmd * cobra.Command , args []string ) {
98- if len (args ) == 0 {
99- log .Fatal ("Enter mysql object's name as an argument" )
100- }
101- dbName = args [0 ]
102-
103- pwd , _ := os .Getwd ()
104- dir := path .Join (pwd , dbName )
105- err := os .MkdirAll (path .Join (dir , logsDir ), dirPerm )
106- if err != nil {
107- log .Fatalln (fmt .Errorf ("failed to create directory %s: %w" , dir , err ))
108- }
109- err = os .MkdirAll (path .Join (dir , yamlsDir ), dirPerm )
110- if err != nil {
111- log .Fatalln (fmt .Errorf ("failed to create directory %s: %w" , dir , err ))
112- }
113- opts .dir = dir
114- opts .db .name = dbName
115-
116- err = opts .populateResourceMap ()
117- if err != nil {
118- log .Fatal (err )
119- }
120-
121- err = opts .collectGitOpsDatabase ()
122- if err != nil {
123- log .Fatal (err )
124- }
125-
126- err = opts .collectDatabase ()
127- if err != nil {
128- log .Fatal (err )
129- }
130-
131- err = opts .collectOperatorLogs (opts .operatorNamespace )
132- if err != nil {
133- log .Fatal (err )
134- }
135-
136- fmt .Println ("Summary:" )
137- for _ , line := range opts .summary {
138- fmt .Println ("- " , line )
139- }
140- fmt .Println ("--------------- Done ---------------" )
141- },
142- }
143-
144- gitOpsDebugCmd .Flags ().StringVarP (& opts .db .namespace , "namespace" , "n" , "demo" , "Database namespace" )
145- gitOpsDebugCmd .Flags ().StringVarP (& opts .operatorNamespace , "operator-namespace" , "o" , "kubedb" , "the namespace where the kubedb gitops operator is installed" )
146- gitOpsDebugCmd .Flags ().StringVarP (& opts .db .resource , "db-type" , "t" , "postgres" , "database type" )
147-
148- return gitOpsDebugCmd
149- }
150-
151- func newGitOpsOpts (f cmdutil.Factory ) * gitOpsOpts {
152- config , err := f .ToRESTConfig ()
63+ func (g * gitOpsOpts ) collectGitOpsYamls () error {
64+ err := g .collectGitOpsDatabase ()
15365 if err != nil {
154- log . Fatalln ( err )
66+ return err
15567 }
15668
157- kc , err := client . New ( config , client. Options { Scheme : scheme } )
158- if err != nil {
159- log . Fatalf ( "failed to create client: %v " , err )
69+ fmt . Println ( "Summary:" )
70+ for _ , line := range g . summary {
71+ fmt . Println ( "- " , line )
16072 }
73+ fmt .Println ("--------------- Done ---------------" )
74+ return nil
75+ }
16176
162- cs , err := kubernetes .NewForConfig (config )
77+ func newGitOpsOpts (kc client.Client , name , namespace , kind , dir string ) (* gitOpsOpts , error ) {
78+ err := os .MkdirAll (dir , dirPerm )
16379 if err != nil {
164- log . Fatalf ( "failed to create kube client: %v" , err )
80+ return nil , err
16581 }
166-
16782 opts := & gitOpsOpts {
168- kc : kc ,
169- config : config ,
170- errWriter : & bytes.Buffer {},
171- kubeClient : cs ,
172- resMap : make (map [string ]string ),
173- summary : make ([]string , 0 ),
83+ kc : kc ,
84+ db : dbInfo {
85+ kind : kind ,
86+ name : name ,
87+ namespace : namespace ,
88+ },
89+ dir : dir ,
90+ summary : make ([]string , 0 ),
17491 }
175- return opts
92+ return opts , nil
17693}
17794
17895func (g * gitOpsOpts ) collectGitOpsDatabase () error {
17996 var uns unstructured.Unstructured
180- uns .SetGroupVersionKind (gitops .SchemeGroupVersion .WithKind (g .getKindFromResource (g .db .resource )))
97+ uns .SetGroupVersionKind (schema.GroupVersionKind {
98+ Group : gitops .SchemeGroupVersion .Group ,
99+ Version : gitops .SchemeGroupVersion .Version ,
100+ Kind : g .db .kind ,
101+ })
181102 err := g .kc .Get (context .Background (), types.NamespacedName {
182103 Namespace : g .db .namespace ,
183104 Name : g .db .name ,
@@ -219,15 +140,19 @@ func (g *gitOpsOpts) collectGitOpsDatabase() error {
219140}
220141
221142func (g * gitOpsOpts ) collectOpsRequests (gitOpsStatus GitOpsStatus ) error {
222- opsYamlDir := path .Join (g .dir , yamlsDir , "ops" )
143+ opsYamlDir := path .Join (g .dir , "ops" )
223144 err := os .MkdirAll (opsYamlDir , dirPerm )
224145 if err != nil {
225146 return err
226147 }
227148 for _ , info := range gitOpsStatus .GitOps .GitOpsInfo {
228149 for _ , op := range info .Operations {
229150 var uns unstructured.Unstructured
230- uns .SetGroupVersionKind (opsapi .SchemeGroupVersion .WithKind (g .getKindFromResource (g .db .resource + "opsrequest" )))
151+ uns .SetGroupVersionKind (schema.GroupVersionKind {
152+ Group : opsapi .SchemeGroupVersion .Group ,
153+ Version : opsapi .SchemeGroupVersion .Version ,
154+ Kind : g .db .kind + "OpsRequest" ,
155+ })
231156 err := g .kc .Get (context .Background (), types.NamespacedName {
232157 Namespace : g .db .namespace ,
233158 Name : op .Name ,
@@ -258,115 +183,3 @@ func (g *gitOpsOpts) collectOpsRequests(gitOpsStatus GitOpsStatus) error {
258183
259184 return nil
260185}
261-
262- func (g * gitOpsOpts ) collectDatabase () error {
263- var uns unstructured.Unstructured
264- uns .SetGroupVersionKind (dbapi .SchemeGroupVersion .WithKind (g .getKindFromResource (g .db .resource )))
265- err := g .kc .Get (context .Background (), types.NamespacedName {
266- Namespace : g .db .namespace ,
267- Name : g .db .name ,
268- }, & uns )
269- if err != nil {
270- log .Fatalf ("failed to get database: %v" , err )
271- }
272-
273- return writeYaml (& uns , path .Join (g .dir , yamlsDir ))
274- }
275-
276- func (g * gitOpsOpts ) collectOperatorLogs (operatorNamespace string ) error {
277- pods , err := g .kubeClient .CoreV1 ().Pods (operatorNamespace ).List (context .TODO (), metav1.ListOptions {})
278- if err != nil {
279- return err
280- }
281- for _ , pod := range pods .Items {
282- isOperatorPod := false
283- for _ , container := range pod .Spec .Containers {
284- if container .Name == operatorContainerName {
285- isOperatorPod = true
286- }
287- }
288- if isOperatorPod {
289- err = g .writeLogs (pod .Name , pod .Namespace , operatorContainerName )
290- if err != nil {
291- return err
292- }
293- }
294- }
295- return nil
296- }
297-
298- func (g * gitOpsOpts ) populateResourceMap () error {
299- dc , err := discovery .NewDiscoveryClientForConfig (g .config )
300- if err != nil {
301- return err
302- }
303- g .resMap = make (map [string ]string )
304-
305- if err := g .populate (dc , "kubedb.com/v1" ); err != nil {
306- return err
307- }
308- if err := g .populate (dc , "kubedb.com/v1alpha2" ); err != nil {
309- return err
310- }
311- if err := g .populate (dc , "gitops.kubedb.com/v1alpha1" ); err != nil {
312- return err
313- }
314- if err := g .populate (dc , "ops.kubedb.com/v1alpha1" ); err != nil {
315- return err
316- }
317- return nil
318- }
319-
320- func (g * gitOpsOpts ) populate (dc * discovery.DiscoveryClient , gv string ) error {
321- resources , err := dc .ServerResourcesForGroupVersion (gv )
322- if err != nil {
323- return err
324- }
325- for _ , r := range resources .APIResources {
326- if ! strings .ContainsAny (r .Name , "/" ) {
327- g .resMap [r .Name ] = r .Kind
328- g .resMap [r .SingularName ] = r .Kind
329- for _ , s := range r .ShortNames {
330- g .resMap [s ] = r .Kind
331- }
332- g .resMap [r .Kind ] = r .Kind
333- }
334- }
335- return nil
336- }
337-
338- func (g * gitOpsOpts ) getKindFromResource (res string ) string {
339- kind , exists := g .resMap [res ]
340- if ! exists {
341- _ = fmt .Errorf ("resource %s not supported" , res )
342- }
343- return kind
344- }
345-
346- func (g * gitOpsOpts ) writeLogs (podName , ns , container string ) error {
347- req := g .kubeClient .CoreV1 ().Pods (ns ).GetLogs (podName , & corev1.PodLogOptions {
348- Container : container ,
349- })
350-
351- podLogs , err := req .Stream (context .TODO ())
352- if err != nil {
353- return err
354- }
355- defer podLogs .Close ()
356-
357- logFile , err := os .Create (path .Join (g .dir , logsDir , podName + "_" + container + ".log" ))
358- if err != nil {
359- return err
360- }
361- defer logFile .Close ()
362-
363- buf := make ([]byte , 1024 )
364- for {
365- bytesRead , err := podLogs .Read (buf )
366- if err != nil {
367- break
368- }
369- _ , _ = logFile .Write (buf [:bytesRead ])
370- }
371- return nil
372- }
0 commit comments