k8s-helper-cli 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- k8s_helper/__init__.py +87 -0
- k8s_helper/cli.py +526 -0
- k8s_helper/config.py +204 -0
- k8s_helper/core.py +511 -0
- k8s_helper/utils.py +301 -0
- k8s_helper_cli-0.1.0.dist-info/METADATA +491 -0
- k8s_helper_cli-0.1.0.dist-info/RECORD +11 -0
- k8s_helper_cli-0.1.0.dist-info/WHEEL +5 -0
- k8s_helper_cli-0.1.0.dist-info/entry_points.txt +2 -0
- k8s_helper_cli-0.1.0.dist-info/licenses/LICENSE +21 -0
- k8s_helper_cli-0.1.0.dist-info/top_level.txt +1 -0
k8s_helper/config.py
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
"""
|
2
|
+
Configuration management for k8s-helper
|
3
|
+
"""
|
4
|
+
|
5
|
+
import os
|
6
|
+
from typing import Dict, Any, Optional
|
7
|
+
import yaml
|
8
|
+
from pathlib import Path
|
9
|
+
|
10
|
+
|
11
|
+
class K8sConfig:
|
12
|
+
"""Configuration class for k8s-helper"""
|
13
|
+
|
14
|
+
def __init__(self, config_file: Optional[str] = None):
|
15
|
+
self.config_file = config_file or self._get_default_config_file()
|
16
|
+
self._config = self._load_config()
|
17
|
+
|
18
|
+
def _get_default_config_file(self) -> str:
|
19
|
+
"""Get the default config file path"""
|
20
|
+
home_dir = Path.home()
|
21
|
+
return str(home_dir / ".k8s-helper" / "config.yaml")
|
22
|
+
|
23
|
+
def _load_config(self) -> Dict[str, Any]:
|
24
|
+
"""Load configuration from file"""
|
25
|
+
if not os.path.exists(self.config_file):
|
26
|
+
return self._get_default_config()
|
27
|
+
|
28
|
+
try:
|
29
|
+
with open(self.config_file, 'r') as f:
|
30
|
+
return yaml.safe_load(f) or {}
|
31
|
+
except Exception as e:
|
32
|
+
print(f"Warning: Could not load config file {self.config_file}: {e}")
|
33
|
+
return self._get_default_config()
|
34
|
+
|
35
|
+
def _get_default_config(self) -> Dict[str, Any]:
|
36
|
+
"""Get default configuration"""
|
37
|
+
return {
|
38
|
+
'default_namespace': 'default',
|
39
|
+
'output_format': 'table', # table, yaml, json
|
40
|
+
'timeout': 300,
|
41
|
+
'auto_wait': True,
|
42
|
+
'verbose': False,
|
43
|
+
'kube_config_path': None, # Use default kubectl config
|
44
|
+
'contexts': {}
|
45
|
+
}
|
46
|
+
|
47
|
+
def save_config(self) -> bool:
|
48
|
+
"""Save configuration to file"""
|
49
|
+
try:
|
50
|
+
# Create directory if it doesn't exist
|
51
|
+
os.makedirs(os.path.dirname(self.config_file), exist_ok=True)
|
52
|
+
|
53
|
+
with open(self.config_file, 'w') as f:
|
54
|
+
yaml.dump(self._config, f, default_flow_style=False, indent=2)
|
55
|
+
return True
|
56
|
+
except Exception as e:
|
57
|
+
print(f"Error saving config: {e}")
|
58
|
+
return False
|
59
|
+
|
60
|
+
def get(self, key: str, default: Any = None) -> Any:
|
61
|
+
"""Get a configuration value"""
|
62
|
+
return self._config.get(key, default)
|
63
|
+
|
64
|
+
def set(self, key: str, value: Any) -> None:
|
65
|
+
"""Set a configuration value"""
|
66
|
+
self._config[key] = value
|
67
|
+
|
68
|
+
def get_namespace(self) -> str:
|
69
|
+
"""Get the default namespace"""
|
70
|
+
return self.get('default_namespace', 'default')
|
71
|
+
|
72
|
+
def set_namespace(self, namespace: str) -> None:
|
73
|
+
"""Set the default namespace"""
|
74
|
+
self.set('default_namespace', namespace)
|
75
|
+
|
76
|
+
def get_output_format(self) -> str:
|
77
|
+
"""Get the output format"""
|
78
|
+
return self.get('output_format', 'table')
|
79
|
+
|
80
|
+
def set_output_format(self, format_type: str) -> None:
|
81
|
+
"""Set the output format"""
|
82
|
+
if format_type in ['table', 'yaml', 'json']:
|
83
|
+
self.set('output_format', format_type)
|
84
|
+
else:
|
85
|
+
raise ValueError("Output format must be 'table', 'yaml', or 'json'")
|
86
|
+
|
87
|
+
def get_timeout(self) -> int:
|
88
|
+
"""Get the default timeout"""
|
89
|
+
return self.get('timeout', 300)
|
90
|
+
|
91
|
+
def set_timeout(self, timeout: int) -> None:
|
92
|
+
"""Set the default timeout"""
|
93
|
+
self.set('timeout', timeout)
|
94
|
+
|
95
|
+
def is_verbose(self) -> bool:
|
96
|
+
"""Check if verbose mode is enabled"""
|
97
|
+
return self.get('verbose', False)
|
98
|
+
|
99
|
+
def set_verbose(self, verbose: bool) -> None:
|
100
|
+
"""Set verbose mode"""
|
101
|
+
self.set('verbose', verbose)
|
102
|
+
|
103
|
+
def get_kube_config_path(self) -> Optional[str]:
|
104
|
+
"""Get the kubectl config path"""
|
105
|
+
return self.get('kube_config_path')
|
106
|
+
|
107
|
+
def set_kube_config_path(self, path: str) -> None:
|
108
|
+
"""Set the kubectl config path"""
|
109
|
+
self.set('kube_config_path', path)
|
110
|
+
|
111
|
+
def add_context(self, name: str, namespace: str, cluster: str = None) -> None:
|
112
|
+
"""Add a context configuration"""
|
113
|
+
contexts = self.get('contexts', {})
|
114
|
+
contexts[name] = {
|
115
|
+
'namespace': namespace,
|
116
|
+
'cluster': cluster
|
117
|
+
}
|
118
|
+
self.set('contexts', contexts)
|
119
|
+
|
120
|
+
def get_context(self, name: str) -> Optional[Dict[str, Any]]:
|
121
|
+
"""Get a context configuration"""
|
122
|
+
contexts = self.get('contexts', {})
|
123
|
+
return contexts.get(name)
|
124
|
+
|
125
|
+
def list_contexts(self) -> Dict[str, Any]:
|
126
|
+
"""List all configured contexts"""
|
127
|
+
return self.get('contexts', {})
|
128
|
+
|
129
|
+
def remove_context(self, name: str) -> bool:
|
130
|
+
"""Remove a context configuration"""
|
131
|
+
contexts = self.get('contexts', {})
|
132
|
+
if name in contexts:
|
133
|
+
del contexts[name]
|
134
|
+
self.set('contexts', contexts)
|
135
|
+
return True
|
136
|
+
return False
|
137
|
+
|
138
|
+
def to_dict(self) -> Dict[str, Any]:
|
139
|
+
"""Get the full configuration as a dictionary"""
|
140
|
+
return self._config.copy()
|
141
|
+
|
142
|
+
def reset_to_defaults(self) -> None:
|
143
|
+
"""Reset configuration to defaults"""
|
144
|
+
self._config = self._get_default_config()
|
145
|
+
|
146
|
+
|
147
|
+
# Global configuration instance
|
148
|
+
_global_config = None
|
149
|
+
|
150
|
+
|
151
|
+
def get_config() -> K8sConfig:
|
152
|
+
"""Get the global configuration instance"""
|
153
|
+
global _global_config
|
154
|
+
if _global_config is None:
|
155
|
+
_global_config = K8sConfig()
|
156
|
+
return _global_config
|
157
|
+
|
158
|
+
|
159
|
+
def set_config_file(config_file: str) -> None:
|
160
|
+
"""Set a custom config file path"""
|
161
|
+
global _global_config
|
162
|
+
_global_config = K8sConfig(config_file)
|
163
|
+
|
164
|
+
|
165
|
+
# Environment variable overrides
|
166
|
+
def get_env_override(key: str, default: Any = None) -> Any:
|
167
|
+
"""Get configuration from environment variables"""
|
168
|
+
env_mapping = {
|
169
|
+
'default_namespace': 'K8S_HELPER_NAMESPACE',
|
170
|
+
'output_format': 'K8S_HELPER_OUTPUT_FORMAT',
|
171
|
+
'timeout': 'K8S_HELPER_TIMEOUT',
|
172
|
+
'verbose': 'K8S_HELPER_VERBOSE',
|
173
|
+
'kube_config_path': 'KUBECONFIG'
|
174
|
+
}
|
175
|
+
|
176
|
+
env_key = env_mapping.get(key)
|
177
|
+
if env_key and env_key in os.environ:
|
178
|
+
value = os.environ[env_key]
|
179
|
+
|
180
|
+
# Convert string values to appropriate types
|
181
|
+
if key == 'timeout':
|
182
|
+
try:
|
183
|
+
return int(value)
|
184
|
+
except ValueError:
|
185
|
+
return default
|
186
|
+
elif key == 'verbose':
|
187
|
+
return value.lower() in ('true', '1', 'yes', 'on')
|
188
|
+
else:
|
189
|
+
return value
|
190
|
+
|
191
|
+
return default
|
192
|
+
|
193
|
+
|
194
|
+
def load_config_with_env_overrides() -> Dict[str, Any]:
|
195
|
+
"""Load configuration with environment variable overrides"""
|
196
|
+
config = get_config()
|
197
|
+
|
198
|
+
# Apply environment overrides
|
199
|
+
for key in ['default_namespace', 'output_format', 'timeout', 'verbose', 'kube_config_path']:
|
200
|
+
env_value = get_env_override(key)
|
201
|
+
if env_value is not None:
|
202
|
+
config.set(key, env_value)
|
203
|
+
|
204
|
+
return config.to_dict()
|