|
|
|
@@ -17,12 +17,12 @@ namespace K8sFileBrowser.ViewModels;
|
|
|
|
|
|
|
|
|
|
|
|
public class MainWindowViewModel : ViewModelBase
|
|
|
|
public class MainWindowViewModel : ViewModelBase
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
#region Properties
|
|
|
|
#region Properties
|
|
|
|
|
|
|
|
|
|
|
|
[Reactive]
|
|
|
|
[Reactive]
|
|
|
|
public string? Version { get; set; } = null!;
|
|
|
|
public string? Version { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
[Reactive]
|
|
|
|
[Reactive]
|
|
|
|
public IEnumerable<ClusterContext> ClusterContexts { get; set; } = null!;
|
|
|
|
public IEnumerable<ClusterContext> ClusterContexts { get; set; } = null!;
|
|
|
|
|
|
|
|
|
|
|
|
@@ -59,12 +59,15 @@ public class MainWindowViewModel : ViewModelBase
|
|
|
|
[Reactive]
|
|
|
|
[Reactive]
|
|
|
|
public Message Message { get; set; } = null!;
|
|
|
|
public Message Message { get; set; } = null!;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private string _lastDirectory = ".";
|
|
|
|
|
|
|
|
|
|
|
|
#endregion Properties
|
|
|
|
#endregion Properties
|
|
|
|
|
|
|
|
|
|
|
|
#region Commands
|
|
|
|
#region Commands
|
|
|
|
|
|
|
|
|
|
|
|
public ReactiveCommand<Unit, Unit> DownloadCommand { get; private set; } = null!;
|
|
|
|
public ReactiveCommand<Unit, Unit> DownloadCommand { get; private set; } = null!;
|
|
|
|
public ReactiveCommand<Unit, Unit> DownloadLogCommand { get; private set; } = null!;
|
|
|
|
public ReactiveCommand<Unit, Unit> DownloadLogCommand { get; private set; } = null!;
|
|
|
|
|
|
|
|
public ReactiveCommand<Unit, Unit> RefreshCommand { get; private set; } = null!;
|
|
|
|
public ReactiveCommand<Unit, Unit> ParentCommand { get; private set; } = null!;
|
|
|
|
public ReactiveCommand<Unit, Unit> ParentCommand { get; private set; } = null!;
|
|
|
|
public ReactiveCommand<Unit, Unit> OpenCommand { get; private set; } = null!;
|
|
|
|
public ReactiveCommand<Unit, Unit> OpenCommand { get; private set; } = null!;
|
|
|
|
private ReactiveCommand<Namespace, IEnumerable<Pod>> GetPodsForNamespace { get; set; } = null!;
|
|
|
|
private ReactiveCommand<Namespace, IEnumerable<Pod>> GetPodsForNamespace { get; set; } = null!;
|
|
|
|
@@ -80,6 +83,7 @@ public class MainWindowViewModel : ViewModelBase
|
|
|
|
// commands
|
|
|
|
// commands
|
|
|
|
ConfigureOpenDirectoryCommand();
|
|
|
|
ConfigureOpenDirectoryCommand();
|
|
|
|
ConfigureDownloadFileCommand(kubernetesService);
|
|
|
|
ConfigureDownloadFileCommand(kubernetesService);
|
|
|
|
|
|
|
|
ConfigureRefreshCommand(kubernetesService);
|
|
|
|
ConfigureDownloadLogCommand(kubernetesService);
|
|
|
|
ConfigureDownloadLogCommand(kubernetesService);
|
|
|
|
ConfigureParentDirectoryCommand();
|
|
|
|
ConfigureParentDirectoryCommand();
|
|
|
|
ConfigureGetPodsForNamespaceCommand(kubernetesService);
|
|
|
|
ConfigureGetPodsForNamespaceCommand(kubernetesService);
|
|
|
|
@@ -96,7 +100,7 @@ public class MainWindowViewModel : ViewModelBase
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#region Property Subscriptions
|
|
|
|
#region Property Subscriptions
|
|
|
|
|
|
|
|
|
|
|
|
private void InitiallyLoadContexts(IKubernetesService kubernetesService)
|
|
|
|
private void InitiallyLoadContexts(IKubernetesService kubernetesService)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// load the cluster contexts when the view model is created
|
|
|
|
// load the cluster contexts when the view model is created
|
|
|
|
@@ -108,14 +112,14 @@ public class MainWindowViewModel : ViewModelBase
|
|
|
|
.Subscribe(x =>
|
|
|
|
.Subscribe(x =>
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ResetNamespaces();
|
|
|
|
ResetNamespaces();
|
|
|
|
ClusterContexts = x;
|
|
|
|
ClusterContexts = x.OrderBy(c => c.Name);
|
|
|
|
|
|
|
|
|
|
|
|
// select the current cluster context
|
|
|
|
// select the current cluster context
|
|
|
|
SelectedClusterContext = ClusterContexts
|
|
|
|
SelectedClusterContext = ClusterContexts
|
|
|
|
.FirstOrDefault(c => c.Name == kubernetesService.GetCurrentContext());
|
|
|
|
.FirstOrDefault(c => c.Name == kubernetesService.GetCurrentContext());
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void RegisterReadNamespaces(IKubernetesService kubernetesService)
|
|
|
|
private void RegisterReadNamespaces(IKubernetesService kubernetesService)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// read the cluster contexts
|
|
|
|
// read the cluster contexts
|
|
|
|
@@ -127,10 +131,10 @@ public class MainWindowViewModel : ViewModelBase
|
|
|
|
.Subscribe(ns =>
|
|
|
|
.Subscribe(ns =>
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ResetPods();
|
|
|
|
ResetPods();
|
|
|
|
Namespaces = ns;
|
|
|
|
Namespaces = ns.OrderBy(n => n.Name);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void RegisterReadPods()
|
|
|
|
private void RegisterReadPods()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// read the pods when the namespace changes
|
|
|
|
// read the pods when the namespace changes
|
|
|
|
@@ -143,10 +147,10 @@ public class MainWindowViewModel : ViewModelBase
|
|
|
|
.Subscribe(x =>
|
|
|
|
.Subscribe(x =>
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ResetContainers();
|
|
|
|
ResetContainers();
|
|
|
|
Pods = x;
|
|
|
|
Pods = x.OrderBy(p => p.Name);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void RegisterReadContainers()
|
|
|
|
private void RegisterReadContainers()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// read the file information when the path changes
|
|
|
|
// read the file information when the path changes
|
|
|
|
@@ -232,9 +236,10 @@ public class MainWindowViewModel : ViewModelBase
|
|
|
|
await Observable.StartAsync(async () =>
|
|
|
|
await Observable.StartAsync(async () =>
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var fileName = SelectedPod?.Name + ".log";
|
|
|
|
var fileName = SelectedPod?.Name + ".log";
|
|
|
|
var saveFileName = await ApplicationHelper.SaveFile(".", fileName);
|
|
|
|
var saveFileName = await ApplicationHelper.SaveFile(_lastDirectory, fileName);
|
|
|
|
if (saveFileName != null)
|
|
|
|
if (saveFileName != null)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
SetLastDirectory(saveFileName);
|
|
|
|
ShowWorkingMessage("Downloading Log...");
|
|
|
|
ShowWorkingMessage("Downloading Log...");
|
|
|
|
await kubernetesService.DownloadLog(SelectedNamespace, SelectedPod, SelectedContainer, saveFileName);
|
|
|
|
await kubernetesService.DownloadLog(SelectedNamespace, SelectedPod, SelectedContainer, saveFileName);
|
|
|
|
HideWorkingMessage();
|
|
|
|
HideWorkingMessage();
|
|
|
|
@@ -245,6 +250,24 @@ public class MainWindowViewModel : ViewModelBase
|
|
|
|
DownloadLogCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
|
|
|
|
DownloadLogCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
|
|
|
|
.Subscribe(ShowErrorMessage);
|
|
|
|
.Subscribe(ShowErrorMessage);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void ConfigureRefreshCommand(IKubernetesService kubernetesService)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var isSelectedContainer = this
|
|
|
|
|
|
|
|
.WhenAnyValue(x => x.SelectedContainer)
|
|
|
|
|
|
|
|
.Select(x => x != null);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RefreshCommand = ReactiveCommand.CreateFromTask(async () =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
await Observable.Start(() =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
FileInformation = GetFileInformation(kubernetesService, SelectedPath!, SelectedPod!, SelectedNamespace!, SelectedContainer!);
|
|
|
|
|
|
|
|
}, RxApp.TaskpoolScheduler);
|
|
|
|
|
|
|
|
}, isSelectedContainer, RxApp.MainThreadScheduler);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RefreshCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
|
|
|
|
|
|
|
|
.Subscribe(ShowErrorMessage);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ConfigureDownloadFileCommand(IKubernetesService kubernetesService)
|
|
|
|
private void ConfigureDownloadFileCommand(IKubernetesService kubernetesService)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@@ -258,9 +281,10 @@ public class MainWindowViewModel : ViewModelBase
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var fileName = SelectedFile!.Name.Substring(SelectedFile!.Name.LastIndexOf('/') + 1,
|
|
|
|
var fileName = SelectedFile!.Name.Substring(SelectedFile!.Name.LastIndexOf('/') + 1,
|
|
|
|
SelectedFile!.Name.Length - SelectedFile!.Name.LastIndexOf('/') - 1);
|
|
|
|
SelectedFile!.Name.Length - SelectedFile!.Name.LastIndexOf('/') - 1);
|
|
|
|
var saveFileName = await ApplicationHelper.SaveFile(".", fileName);
|
|
|
|
var saveFileName = await ApplicationHelper.SaveFile(_lastDirectory, fileName);
|
|
|
|
if (saveFileName != null)
|
|
|
|
if (saveFileName != null)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
SetLastDirectory(saveFileName);
|
|
|
|
ShowWorkingMessage("Downloading File...");
|
|
|
|
ShowWorkingMessage("Downloading File...");
|
|
|
|
await kubernetesService.DownloadFile(SelectedNamespace, SelectedPod, SelectedContainer, SelectedFile, saveFileName);
|
|
|
|
await kubernetesService.DownloadFile(SelectedNamespace, SelectedPod, SelectedContainer, SelectedFile, saveFileName);
|
|
|
|
HideWorkingMessage();
|
|
|
|
HideWorkingMessage();
|
|
|
|
@@ -272,6 +296,11 @@ public class MainWindowViewModel : ViewModelBase
|
|
|
|
.Subscribe(ShowErrorMessage);
|
|
|
|
.Subscribe(ShowErrorMessage);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void SetLastDirectory(string saveFileName)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
_lastDirectory = saveFileName.Substring(0, saveFileName.LastIndexOf('\\'));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ConfigureOpenDirectoryCommand()
|
|
|
|
private void ConfigureOpenDirectoryCommand()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var isDirectory = this
|
|
|
|
var isDirectory = this
|
|
|
|
@@ -290,11 +319,11 @@ public class MainWindowViewModel : ViewModelBase
|
|
|
|
OpenCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
|
|
|
|
OpenCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
|
|
|
|
.Subscribe(ShowErrorMessage);
|
|
|
|
.Subscribe(ShowErrorMessage);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion Configure Commands
|
|
|
|
#endregion Configure Commands
|
|
|
|
|
|
|
|
|
|
|
|
#region Get Data
|
|
|
|
#region Get Data
|
|
|
|
|
|
|
|
|
|
|
|
private static async Task<IEnumerable<Pod>> PodsAsync(Namespace? ns, IKubernetesService kubernetesService)
|
|
|
|
private static async Task<IEnumerable<Pod>> PodsAsync(Namespace? ns, IKubernetesService kubernetesService)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (ns == null)
|
|
|
|
if (ns == null)
|
|
|
|
@@ -346,67 +375,74 @@ public class MainWindowViewModel : ViewModelBase
|
|
|
|
Parent = parent
|
|
|
|
Parent = parent
|
|
|
|
}).ToList();
|
|
|
|
}).ToList();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion Get Data
|
|
|
|
#endregion Get Data
|
|
|
|
|
|
|
|
|
|
|
|
#region Reset Data
|
|
|
|
#region Reset Data
|
|
|
|
|
|
|
|
|
|
|
|
private void ResetPath()
|
|
|
|
private void ResetPath()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
FileInformation = new List<FileInformation>();
|
|
|
|
FileInformation = new List<FileInformation>();
|
|
|
|
SelectedPath = null;
|
|
|
|
SelectedPath = null;
|
|
|
|
SelectedContainer = null;
|
|
|
|
SelectedContainer = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ResetContainers()
|
|
|
|
private void ResetContainers()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ResetPath();
|
|
|
|
ResetPath();
|
|
|
|
Containers = new List<Container>();
|
|
|
|
Containers = new List<Container>();
|
|
|
|
SelectedPod = null;
|
|
|
|
SelectedPod = null;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ResetPods()
|
|
|
|
private void ResetPods()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ResetContainers();
|
|
|
|
ResetContainers();
|
|
|
|
SelectedNamespace = null;
|
|
|
|
SelectedNamespace = null;
|
|
|
|
Pods = new List<Pod>();
|
|
|
|
Pods = new List<Pod>();
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ResetNamespaces()
|
|
|
|
private void ResetNamespaces()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ResetPods();
|
|
|
|
ResetPods();
|
|
|
|
Namespaces = new List<Namespace>();
|
|
|
|
Namespaces = new List<Namespace>();
|
|
|
|
SelectedClusterContext = null;
|
|
|
|
SelectedClusterContext = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion Reset Data
|
|
|
|
#endregion Reset Data
|
|
|
|
|
|
|
|
|
|
|
|
#region show messages
|
|
|
|
#region show messages
|
|
|
|
|
|
|
|
|
|
|
|
private void ShowWorkingMessage(string message)
|
|
|
|
private void ShowWorkingMessage(string message)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Message = new Message
|
|
|
|
RxApp.MainThreadScheduler.Schedule(Action);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Action()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
IsVisible = true,
|
|
|
|
Message = new Message
|
|
|
|
Text = message,
|
|
|
|
{
|
|
|
|
IsError = false
|
|
|
|
IsVisible = true,
|
|
|
|
};
|
|
|
|
Text = message,
|
|
|
|
|
|
|
|
IsError = false
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ShowErrorMessage(string message)
|
|
|
|
private void ShowErrorMessage(string message)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
RxApp.MainThreadScheduler.Schedule(Action);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
async void Action()
|
|
|
|
async void Action()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Message = new Message { IsVisible = true, Text = message, IsError = true };
|
|
|
|
Message = new Message { IsVisible = true, Text = message, IsError = true };
|
|
|
|
await Task.Delay(7000);
|
|
|
|
await Task.Delay(7000);
|
|
|
|
HideWorkingMessage();
|
|
|
|
HideWorkingMessage();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
RxApp.MainThreadScheduler.Schedule(Action);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ShowErrorMessage(Exception exception)
|
|
|
|
private void ShowErrorMessage(Exception exception)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// ReSharper disable once TemplateIsNotCompileTimeConstantProblem
|
|
|
|
// ReSharper disable once TemplateIsNotCompileTimeConstantProblem
|
|
|
|
@@ -423,6 +459,6 @@ public class MainWindowViewModel : ViewModelBase
|
|
|
|
IsError = false
|
|
|
|
IsError = false
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion show messages
|
|
|
|
#endregion show messages
|
|
|
|
}
|
|
|
|
}
|