Skip to content

Commit d543fff

Browse files
author
欧林宝
authored
Merge pull request #1 from oulinbao/master
release 0.1.0
2 parents 22808fb + bb5f016 commit d543fff

73 files changed

Lines changed: 10539 additions & 1 deletion

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.idea
2+
build/
3+
dist/
4+
*.egg-info
5+
*.pyc
6+
.pytest_cache/
7+
.DS_Store

README

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# 京东云CLI
2+
京东云CLI提供使用命令行的方式访问您的云中资源。
3+
4+
## 安装方法:
5+
### Linux && Mac
6+
pip安装:
7+
`pip install jdcloud_cli`
8+
9+
源码安装:
10+
`python setup.py install`
11+
12+
安装后执行:
13+
```
14+
echo 'eval "$(register-python-argcomplete jdc)"' >> .bashrc
15+
echo 'export COLUMNS=100' >> .bashrc
16+
source ~/.bashrc
17+
```
18+
19+
20+
### Windows

README.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

jdcloud_cli/__init__.py

Whitespace-only changes.

jdcloud_cli/client_factory.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# coding=utf8
2+
3+
# Copyright 2018 JDCLOUD.COM
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http:#www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
# NOTE: This class is auto generated by the jdcloud code generator program.
18+
19+
from jdcloud_sdk.core.config import Config
20+
from jdcloud_sdk.core.credential import Credential
21+
from jdcloud_sdk.services.vm.client.VmClient import VmClient
22+
from jdcloud_sdk.services.iam.client.IamClient import IamClient
23+
from jdcloud_sdk.services.disk.client.DiskClient import DiskClient
24+
from jdcloud_sdk.services.mongodb.client.MongodbClient import MongodbClient
25+
from jdcloud_sdk.services.mps.client.MpsClient import MpsClient
26+
from jdcloud_sdk.services.streambus.client.StreambusClient import StreambusClient
27+
from jdcloud_sdk.services.ipanti.client.IpantiClient import IpantiClient
28+
from jdcloud_sdk.services.rds.client.RdsClient import RdsClient
29+
from jdcloud_sdk.services.redis.client.RedisClient import RedisClient
30+
from jdcloud_sdk.services.monitor.client.MonitorClient import MonitorClient
31+
from jdcloud_sdk.services.vpc.client.VpcClient import VpcClient
32+
from jdcloud_sdk.services.xdata.client.XdataClient import XdataClient
33+
from jdcloud_sdk.services.nc.client.NcClient import NcClient
34+
from jdcloud_sdk.services.oss.client.OssClient import OssClient
35+
from jdcloud_cli.config import ProfileManager
36+
from jdcloud_cli.logger import get_logger
37+
38+
39+
class ClientFactory(object):
40+
41+
def __init__(self, service):
42+
self.__service = service
43+
44+
def get(self, app):
45+
client_map = {
46+
'vm': VmClient,
47+
'iam': IamClient,
48+
'disk': DiskClient,
49+
'mongodb': MongodbClient,
50+
'mps': MpsClient,
51+
'streambus': StreambusClient,
52+
'ipanti': IpantiClient,
53+
'rds': RdsClient,
54+
'redis': RedisClient,
55+
'monitor': MonitorClient,
56+
'vpc': VpcClient,
57+
'xdata': XdataClient,
58+
'nc': NcClient,
59+
'oss': OssClient,
60+
}
61+
62+
profile_manager = ProfileManager()
63+
cli_config = profile_manager.load_current_profile()
64+
if cli_config is None:
65+
return None
66+
67+
logger = get_logger(app.pargs.debug)
68+
69+
config = Config(cli_config.endpoint, cli_config.scheme)
70+
credential = Credential(cli_config.access_key, cli_config.secret_key)
71+
if self.__service not in client_map:
72+
return None
73+
74+
client = client_map[self.__service](credential, config, logger)
75+
return client

jdcloud_cli/config.py

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# coding=utf8
2+
3+
# Copyright 2018 JDCLOUD.COM
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http:#www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
import os
18+
from configparser import SafeConfigParser
19+
20+
CONF_AK = 'access_key'
21+
CONF_SK = 'secret_key'
22+
CONF_REGION = 'region_id'
23+
CONF_ENDPOINT = 'endpoint'
24+
CONF_SCHEME = 'scheme'
25+
26+
27+
class Config(object):
28+
29+
def __init__(self, access_key, secret_key, region_id, endpoint, scheme):
30+
self.access_key = access_key
31+
self.secret_key = secret_key
32+
self.region_id = region_id
33+
self.endpoint = endpoint
34+
self.scheme = scheme
35+
36+
37+
class ProfileManager(object):
38+
39+
def __new__(type):
40+
if '_instance' not in type.__dict__:
41+
type._instance = object.__new__(type)
42+
return type._instance
43+
44+
def __init__(self):
45+
cli_dir = self.__make_config_dir()
46+
self.__config_file = cli_dir + '/config'
47+
self.__current_file = cli_dir + '/current'
48+
self.__current_profile_name = self.__get_current_profile_name()
49+
self.__parser = SafeConfigParser()
50+
self.__parser.read(self.__config_file)
51+
52+
def load_current_profile(self):
53+
if self.__current_profile_name not in self.__parser.sections():
54+
print 'Please use `jdc configure add` command to add cli configure first.'
55+
return None
56+
57+
# notice that the type of config info which read from file is unicode
58+
# python SDK uses type str
59+
access_key = str(self.__parser.get(self.__current_profile_name, CONF_AK))
60+
secret_key = str(self.__parser.get(self.__current_profile_name, CONF_SK))
61+
region_id = str(self.__parser.get(self.__current_profile_name, CONF_REGION))
62+
endpoint = str(self.__parser.get(self.__current_profile_name, CONF_ENDPOINT))
63+
scheme = str(self.__parser.get(self.__current_profile_name, CONF_SCHEME))
64+
return Config(access_key, secret_key, region_id, endpoint, scheme)
65+
66+
def get_all_profiles(self):
67+
result = dict()
68+
sections = self.__parser.sections()
69+
for section in sections:
70+
result[section] = self.__parser.items(section)
71+
return result
72+
73+
def get_current_profile(self):
74+
result = dict()
75+
if not self.__parser.has_section(self.__current_profile_name):
76+
return result
77+
78+
result[self.__current_profile_name] = self.__parser.items(self.__current_profile_name)
79+
80+
return result
81+
82+
def add_profile(self, profile, config):
83+
if self.__parser.has_section(profile):
84+
return False, 'Profile ' + profile + ' has existed'
85+
86+
self.__parser.add_section(profile)
87+
88+
# use enums for the fields order
89+
for key in [CONF_AK, CONF_SK, CONF_REGION, CONF_ENDPOINT, CONF_SCHEME]:
90+
value = config.__dict__[key]
91+
self.__parser.set(profile, key, value)
92+
93+
return self.__write_config_file()
94+
95+
def delete_profile(self, profile):
96+
if not self.__parser.has_section(profile):
97+
return False, 'No profile ' + profile
98+
99+
if profile == self.__current_profile_name:
100+
return False, 'Can not delete current profile: ' + profile
101+
102+
self.__parser.remove_section(profile)
103+
return self.__write_config_file()
104+
105+
def set_current_profile(self, name):
106+
if not self.__parser.has_section(name):
107+
return False, 'Profile %s do not exist! Configure failed!' % name
108+
try:
109+
with open(self.__current_file, 'w') as f:
110+
f.write(name)
111+
self.__current_profile_name = name
112+
except Exception as e:
113+
return False, e.message
114+
return True, ''
115+
116+
def __write_config_file(self):
117+
try:
118+
with open(self.__config_file, 'w+') as f:
119+
self.__parser.write(f)
120+
except Exception as e:
121+
return False, e.message
122+
return True, ''
123+
124+
def __make_config_dir(self):
125+
home = os.path.expanduser("~")
126+
cli_dir = home + "/.jdc"
127+
if not os.path.exists(cli_dir):
128+
os.makedirs(cli_dir)
129+
return cli_dir
130+
131+
def __get_current_profile_name(self):
132+
if not os.path.exists(self.__current_file):
133+
with open(self.__current_file, 'w') as f:
134+
f.write('default')
135+
return 'default'
136+
137+
with open(self.__current_file, 'r') as f:
138+
name = f.read()
139+
return name

jdcloud_cli/const.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# coding=utf8
2+
3+
# Copyright 2018 JDCLOUD.COM
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http:#www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
WEBSOCKET_SCHEME = 'ws'
18+
19+
METHOD_GET = 'GET'
20+
21+
REGION_ID = 'regionId'

jdcloud_cli/controllers/__init__.py

Whitespace-only changes.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# coding=utf8
2+
3+
# Copyright 2018 JDCLOUD.COM
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http:#www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
from cement.ext.ext_argparse import ArgparseController
18+
from jdcloud_cli.version import VERSION
19+
20+
21+
class BaseController(ArgparseController):
22+
class Meta:
23+
label = 'base'
24+
arguments = [
25+
(['--output'], dict(help='output format', choices=['json'], default='json')),
26+
(['-v', '--version'], dict(action='version', version=VERSION)),
27+
]

0 commit comments

Comments
 (0)