Skip to content

Commit 532f865

Browse files
author
Robin Hermann
committed
fix: change structure (missing files)
1 parent 5d7dc47 commit 532f865

File tree

5 files changed

+251
-0
lines changed

5 files changed

+251
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net7.0-windows7.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
<AssemblyName>Flow.Launcher.Plugin.KubernetesContextSwitcher</AssemblyName>
8+
<RootNamespace>Flow.Launcher.Plugin.KubernetesContextSwitcher</RootNamespace>
9+
<Version>1.0.1</Version>
10+
<Authors>Robin Hermann</Authors>
11+
<Description>A Flow Launcher plugin to switch Kubernetes contexts quickly</Description>
12+
<PackageId>Flow.Launcher.Plugin.KubernetesContextSwitcher</PackageId>
13+
</PropertyGroup>
14+
15+
<ItemGroup>
16+
<PackageReference Include="Flow.Launcher.Plugin" Version="4.6.0" />
17+
</ItemGroup>
18+
19+
</Project>
73.3 KB
Loading
73.3 KB
Loading
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
using Flow.Launcher.Plugin;
2+
using System.Diagnostics;
3+
using System.Text.Json;
4+
5+
namespace Flow.Launcher.Plugin.KubernetesContextSwitcher;
6+
7+
public class Main : IPlugin
8+
{
9+
private PluginInitContext _context = null!;
10+
private string _kubectlPath = "kubectl";
11+
12+
public void Init(PluginInitContext context)
13+
{
14+
_context = context;
15+
16+
// Try to find kubectl in PATH or common locations
17+
var kubectlPaths = new[]
18+
{
19+
"kubectl",
20+
@"C:\Program Files\Docker\Docker\resources\bin\kubectl.exe",
21+
@"C:\Users\%USERNAME%\AppData\Local\Microsoft\WinGet\Packages\Kubernetes.kubectl_Microsoft.Winget.Source_8wekyb3d8bbwe\kubectl.exe"
22+
};
23+
24+
foreach (var path in kubectlPaths)
25+
{
26+
if (File.Exists(path) || IsCommandAvailable(path))
27+
{
28+
_kubectlPath = path;
29+
break;
30+
}
31+
}
32+
}
33+
34+
public List<Result> Query(Query query)
35+
{
36+
var results = new List<Result>();
37+
var searchTerm = query.Search.Trim();
38+
39+
try
40+
{
41+
if (string.IsNullOrEmpty(searchTerm))
42+
{
43+
// Show current context and available contexts
44+
var currentContext = GetCurrentContext();
45+
var contexts = GetAvailableContexts();
46+
47+
results.Add(new Result
48+
{
49+
Title = $"Current: {currentContext}",
50+
SubTitle = "Current Kubernetes context",
51+
IcoPath = "Images/k8s.png",
52+
Score = 100
53+
});
54+
55+
foreach (var context in contexts.Where(c => c != currentContext))
56+
{
57+
results.Add(new Result
58+
{
59+
Title = context,
60+
SubTitle = $"Switch to {context}",
61+
IcoPath = "Images/k8s.png",
62+
Score = 90,
63+
Action = e =>
64+
{
65+
SwitchContext(context);
66+
_context.API.ShowMsg($"Switched to context: {context}");
67+
return true;
68+
}
69+
});
70+
}
71+
}
72+
else
73+
{
74+
// Filter contexts based on search term
75+
var contexts = GetAvailableContexts()
76+
.Where(c => c.Contains(searchTerm, StringComparison.OrdinalIgnoreCase))
77+
.ToList();
78+
79+
var currentContext = GetCurrentContext();
80+
81+
foreach (var context in contexts)
82+
{
83+
var isCurrent = context == currentContext;
84+
results.Add(new Result
85+
{
86+
Title = context + (isCurrent ? " (current)" : ""),
87+
SubTitle = isCurrent ? "Current context" : $"Switch to {context}",
88+
IcoPath = "Images/k8s.png",
89+
Score = isCurrent ? 80 : 90,
90+
Action = isCurrent ? null : e =>
91+
{
92+
SwitchContext(context);
93+
_context.API.ShowMsg($"Switched to context: {context}");
94+
return true;
95+
}
96+
});
97+
}
98+
}
99+
}
100+
catch (Exception ex)
101+
{
102+
results.Add(new Result
103+
{
104+
Title = "Error",
105+
SubTitle = ex.Message,
106+
IcoPath = "Images/error.png",
107+
Score = 0
108+
});
109+
}
110+
111+
return results;
112+
}
113+
114+
private string GetCurrentContext()
115+
{
116+
var startInfo = new ProcessStartInfo
117+
{
118+
FileName = _kubectlPath,
119+
Arguments = "config current-context",
120+
RedirectStandardOutput = true,
121+
RedirectStandardError = true,
122+
UseShellExecute = false,
123+
CreateNoWindow = true
124+
};
125+
126+
using var process = Process.Start(startInfo);
127+
if (process == null)
128+
throw new Exception("Failed to start kubectl process");
129+
130+
var output = process.StandardOutput.ReadToEnd();
131+
var error = process.StandardError.ReadToEnd();
132+
process.WaitForExit();
133+
134+
if (process.ExitCode != 0)
135+
throw new Exception($"kubectl error: {error}");
136+
137+
return output.Trim();
138+
}
139+
140+
private List<string> GetAvailableContexts()
141+
{
142+
var startInfo = new ProcessStartInfo
143+
{
144+
FileName = _kubectlPath,
145+
Arguments = "config get-contexts -o name",
146+
RedirectStandardOutput = true,
147+
RedirectStandardError = true,
148+
UseShellExecute = false,
149+
CreateNoWindow = true
150+
};
151+
152+
using var process = Process.Start(startInfo);
153+
if (process == null)
154+
throw new Exception("Failed to start kubectl process");
155+
156+
var output = process.StandardOutput.ReadToEnd();
157+
var error = process.StandardError.ReadToEnd();
158+
process.WaitForExit();
159+
160+
if (process.ExitCode != 0)
161+
throw new Exception($"kubectl error: {error}");
162+
163+
return output.Split('\n', StringSplitOptions.RemoveEmptyEntries)
164+
.Select(line => line.Trim())
165+
.Where(line => !string.IsNullOrEmpty(line))
166+
.ToList();
167+
}
168+
169+
private void SwitchContext(string contextName)
170+
{
171+
var startInfo = new ProcessStartInfo
172+
{
173+
FileName = _kubectlPath,
174+
Arguments = $"config use-context {contextName}",
175+
RedirectStandardOutput = true,
176+
RedirectStandardError = true,
177+
UseShellExecute = false,
178+
CreateNoWindow = true
179+
};
180+
181+
using var process = Process.Start(startInfo);
182+
if (process == null)
183+
throw new Exception("Failed to start kubectl process");
184+
185+
var output = process.StandardOutput.ReadToEnd();
186+
var error = process.StandardError.ReadToEnd();
187+
process.WaitForExit();
188+
189+
if (process.ExitCode != 0)
190+
throw new Exception($"Failed to switch context: {error}");
191+
}
192+
193+
private bool IsCommandAvailable(string command)
194+
{
195+
try
196+
{
197+
var startInfo = new ProcessStartInfo
198+
{
199+
FileName = "where",
200+
Arguments = command,
201+
RedirectStandardOutput = true,
202+
UseShellExecute = false,
203+
CreateNoWindow = true
204+
};
205+
206+
using var process = Process.Start(startInfo);
207+
if (process == null) return false;
208+
209+
var output = process.StandardOutput.ReadToEnd();
210+
process.WaitForExit();
211+
212+
return process.ExitCode == 0 && !string.IsNullOrEmpty(output.Trim());
213+
}
214+
catch
215+
{
216+
return false;
217+
}
218+
}
219+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"ID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
3+
"ActionKeyword": "k8s",
4+
"Name": "Kubernetes Context Switcher",
5+
"Description": "Switch between Kubernetes contexts quickly",
6+
"Author": "Robin Hermann",
7+
"Version": "1.0.1",
8+
"Language": "csharp",
9+
"Website": "https://github.com/r-studio/Flow.Launcher.Plugin.KubernetesContextSwitcher",
10+
"IcoPath": "Images\\k8s.png",
11+
"ExecuteFileName": "Flow.Launcher.Plugin.KubernetesContextSwitcher.dll",
12+
"Disabled": false
13+
}

0 commit comments

Comments
 (0)