Ansible基础 、 Ansible编程 、 编写ansible模块案例

Top

NSD Devops DAY02

  1. 案例1:通过本机发送邮件
  2. 案例2:通过互联网服务器发送邮件
  3. 案例3:天气预报查询
  4. 案例4:钉钉机器人
  5. 案例5:获取zabbix版本信息
  6. 案例6:获取令牌
  7. 案例7:创建主机

1 案例1:通过本机发送邮件

1.1 问题

编写一个send_mail.py脚本,实现以下功能:

  1. 创建bob和alice帐户
  2. 编写发送邮件件程序,发件人为root,收件人是本机的bob和alice帐户

1.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建bob和alice帐户

[root@ localhost day12]# ls /home/
Student  zabbix  zhangsan
[root@localhost day12]# useradd bob
[root@localhost day12]# useradd alice
[root@localhost day12]# ls /home/
alice  bob  Student  zabbix  zhangsan

步骤二:编写发送邮件件程序,发件人为root,收件人是本机的bob和alice帐户

[root@ localhost day12]# vim send_mail.py

import smtplib
from email.mime.text import MIMEText
from email.header import Header
#邮件正文有三个参数:第一个为文本内容,第二个设置文本格式plain,第三个utf-8设置编码保证多语言兼容性
message = MIMEText('Python邮件发送测试\n', 'plain', 'utf8')	
标准邮件需要三个头部信息: From, To, 和 Subject
#发送者信息
message['From'] = Header('root@localhost', 'utf8')	
#接收者信息
message['To'] = Header('bob@localhost', 'utf8')
#主题信息
message['Subject'] = Header('mail test', 'utf8')

sender = 'root@redhat.com'		#发送方
receivers = ['bob@localhost', 'alice@126.com']	#收件方
smtp_obj = smtplib.SMTP('localhost')	#用localhost发邮件
# smtplib负责发送邮件
smtp_obj.sendmail(sender, receivers, message.as_string())

SMTP是发送邮件的协议,Python内置对SMTP的支持,可以发送纯文本邮件、HTML邮件以及带附件的邮件。

Python对SMTP支持有smtplib和email两个模块,email负责构造邮件,smtplib负责发送邮件。

Python SMTP 对象使用 sendmail 方法发送邮件:

smtp_obj.sendmail(sender, receivers, message.as_string())

参数说明:

sender: 邮件发送者地址。

receivers: 字符串列表,邮件发送地址。

message.as_string(): 发送消息 ,str模式

由于可以一次发给多个人,所以recives传入一个列表,邮件正文是一个str,as_string()把MIMEText对象变成str。

步骤三:测试脚本执行

[root@ localhost day12]# python3 send_mail.py
[root@ localhost day12]# mail –u bob
Heirloom Mail version 12.5 7/5/10.  Type ? for help.
“/var/mail/bob”: 1 message 1 new
>N  1 =?utf8?q?root=4Oloca  Mon Jul 30 09:36  18?663  “”
& 1
From root@redhat.com Mon Jul 30 09:36:44 2018
Return- Path: <root@redhat.com>
X- Original- To: bob@localhost.tedu.cn
Content- Type: text/plain; charset=“utf8”
From: root@localhost@room8pc16.tedu.cn
To: bob@localhost@room8pc16.tedu.cn
Subject: mail test
Date: Mon, 30 Jul 2018 09:36:44 +0800 (CST)
Status: R

Python邮件发送测试
&

2 案例2:通过互联网服务器发送邮件

2.1 问题

编写一个mail_client.py脚本,实现以下功能:

  1. 通过自己互联网注册的邮箱,为其他同学互联网邮箱发邮件

2.2 方案

导入sys模块,用sys.argv方法获取get_web函数实参,让用户在命令行上提供http://www.tedu.cn和/tmp/tedu.html两个参数,调用get_web函数实现如下功能:

1)导入urllib模块,使用urllib模块的urlopen函数打开url(即网址),赋值给html

2)以写方式打开/tmp/tedu.html文件

3)以循环方式:

读html获取的数据,保存到data

将data写入/tmp/tedu.html

4)关闭html

2.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:环境准备

使用SMTP协议发送的邮件,需要先查看您的发件人邮箱是否有开启SMTP协议,如没有需要开启,测试使用的是126.com的邮箱作为发信人邮箱,开启SMTP协议如下

1. 先登录到126.com邮箱,如图-1所示:

图-1

2. 看到邮箱上面的功能栏中有一个“设置”的选项,单击该选项,然后选择下拉菜单的“POP3/SMTP/IMAP”,如图-2所示:

图-2

3. 如图-3所示,上面红框的两个必须勾选上,如没有勾选,要选择开启就可以勾选上了:

图-3

4.页面向下可以可以看到下图-4红框里是:SMTP服务器是:smtp.126.com:

图-4

步骤二:编写脚本

[root@ localhost day12]# vim mail_client.py
#!/usr/bin/env python3

import smtplib
from getpass import getpass
from email.mime.text import MIMEText
from email.header import Header

mail_host = 'smtp.126.com'		#发件人邮箱账号
mail_user = 'zhangzhigang79@126.com'		#收件人邮箱账号
mail_pwd = getpass()		#获取密码
#邮件正文有三个参数:第一个为文本内容,第二个设置文本格式plain,第三个utf-8设置编码保证多语言兼容性
message = MIMEText('Python邮件发送测试\n', 'plain', 'utf8')
#发送者信息
message['From'] = Header('zhangzhigang79@126.com', 'utf8')
#接收者信息
message['To'] = Header('zhangzhigang79@126.com', 'utf8')
#主题信息
message['Subject'] = Header('python 1802 mail test', 'utf8')

sender = 'zhangzhigang79@126.com'		#发送方
receivers = ['zhangzhigang79@126.com']		#接收方
smtp_obj = smtplib.SMTP()		#创建SMTP对象
smtp_obj.connect(mail_host)	#将SMTP对象与发送人邮件简历连接建立连接
smtp_obj.login(mail_user, mail_pwd)		#登录用户名密码
# SMTP 对象使用 sendmail 方法发送邮件
smtp_obj.sendmail(sender, receivers, message.as_string())

步骤三:测试脚本执行

[root@ localhost day12]# python3 mail_client.py
Password:

如果发送成功,结果显示如图-5所示:

图-5

3 案例3:天气预报查询

3.1 问题

编写一个display_weather.py脚本,实现以下功能:

  1. 运行程序时,屏幕将出现你所在城市各区县名字
  2. 用户指定查询某区县,屏幕上将出现该区县当前的气温、湿度、风向、风速等

3.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:找到天气信息规律

1.首先我们想要实现的功能是天气预报,从哪获取天气这是一个问题,在这里可以使用http://www.weather.com.cn/data/sk/101051301.html这个应用程序编程接口,101051301是城市的ID,可以到http://www.weather.com.cn/查看,替换后浏览器打开,如图-6所示,图示为json格式:

图-6

注意:图中看不懂的文字是编码问题

2.从图-1中可以看出cityid就是城市ID,temp是温度,SD是湿度,我们编写代码可以直接获取到网站相应信息,编写脚本wather.py:

[root@ localhost day12]# vim weather.py
#!/usr/bin/python     #这里是python的目录
from urllib.request import urlopen
import json

#打开网页,使用urllib模块的urlopen函数打开url,赋值给html
html = urlopen('http://www.weather.com.cn/data/sk/101010100.html')
#读html获取的数据,保存到data
data = html.read()
#从data中获取我们想要的信息,json.loads()是将json格式数据转换为字典
#(可以理解为json.loads()函数是将字符串转化为字典)
print(json.loads(data))
#关闭html
html.close()

3.执行脚本结果如下:

[root@ localhost day12]# python3 weather.py
{‘weatherinfo’:{‘city’:‘北京’,‘cityid’:‘101010100’,‘temp’:‘27.9’,‘WD’:‘南风’,‘WS’:‘小于3级’,‘SD’:‘28%’,‘AP’:‘1002hPa’,‘njd’:‘暂无实况’,‘WSE’:‘<3’,‘time’:‘17:55’,‘sm’:‘2.1’,‘isRadar’:‘1’,‘Radar’:‘JC_RADAR_AZ9010_JB’}}

从以上脚本执行结果中我们可以看到,从网站中获取到的数据是以字典形式显示,显示信息有城市、城市id,温度、风向等等,根据这种规律,编写下面代码

步骤二:编写代码实现如下功能

1.定义一个字典,该字典中键‘0’和‘1’对应的值为天气网址中城市对应的id,城市不同id则不同

2.运行程序时,屏幕将出现你所在城市名字

3.当用户指定查询某城市(即输入0或1时)

4.调用get_weather函数,函数的实际参数为city_codes字典对应值(即对应的城市id)

5. 打开天气网页,使用urllib模块的urlopen函数打开url,赋值给html

6.读html获取的数据,用json.loads()获取天气信息,获取到的信息为字典形式

7.从获取到的字典数据中提取气温、湿度、风向、风速等信息,保存在output变量中

8.将output变量作为get_weather函数的返回值,打印在屏幕上

[root@ localhost day12]# vim display_weather.py
#!/usr/bin/python

from urllib.request import urlopen
import json

def get_weather(city_code):		#定义一个输入城市id的函数
5.打开天气网页,使用urllib模块的urlopen函数打开url,赋值给html
    url = 'http://www.weather.com.cn/data/sk/%s.html' % city_code
    html = urlopen(url)
6.读html获取的数据,用json.loads()获取我们想要的信息
#json.loads()是将json格式数据转换为字典
#(可以理解为json.loads()函数是将字符串转化为字典)
    data = json.loads(html.read())
7.output为返回值,即最终屏幕显示的信息
    output = '风向:%s, 风力: %s, 温度:%s, 湿度:%s' % (
#data获取到的天气信息为字典,该字典中weatherinfo键对应的值还是一个字典,这个字典中‘WD’键对应的值是风向,‘WS’键对应的值是风力,'temp'键对应的值是温度,'SD'键对应的值是湿度,利用键值对关系将相应数据显示出来即可
        data['weatherinfo']['WD'],
        data['weatherinfo']['WS'],
        data['weatherinfo']['temp'],
        data['weatherinfo']['SD']
    )
    return output



if __name__ == '__main__':
1.定义字典:键对应的值为天气网站网址接口中城市ID
    city_codes = { '0': '101010100', '1': '101121404'}
2.代码执行后,屏幕给出的提示信息
    prompt = """(0) 北京
(1) 台儿庄
请选择(0/1): """
3.根据提示信息,输入0或1
    choice = input(prompt)
4.调用get_weather函数,其实际参数为city_codes字典对应值
8.打印调用get_weather函数返回值
    print(get_weather(city_codes[choice]))

步骤三:测试脚本执行

[root@ localhost day12]# python3 display_weather.py
(0) 北京
(1) 台儿庄
请选择(0/1): 0
 风向:南风, 风力: 小于3级, 温度:27.9, 湿度:28%
[root@ localhost day12]# python3 display_weather.py
(0) 北京
(1) 台儿庄
请选择(0/1): 1
 风向:东北风, 风力: 小于3级, 温度:22.3, 湿度:64%

4 案例4:钉钉机器人

4.1 问题

通过钉钉软件创建一个群聊机器人,要求:

  1. 编写代码,通过python脚本实现钉钉机器人在群中发送消息
  2. 使用json和requests模块

4.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:在钉钉中创建群聊机器人

/

图-7

 

/

图-8

 

/

图-9

 

/

图-10

 

/

图-11

 

步骤二:编写代码

[root@ localhost day12]# vim dingtalk.py
import json
import requests
import sys


def send_msg(url, reminders, msg):
    headers = {'Content-Type': 'application/json;charset=utf-8'}
    data = {
        "msgtype": "text",  # 发送消息类型为文本
        "at": {
            "atMobiles": reminders,
            "isAtAll": False,   # 不@所有人
        },
        "text": {
            "content": msg,   # 消息正文
        }
    }
    r = requests.post(url, data=json.dumps(data), headers=headers)
    return r.text

if __name__ == '__main__':
    msg = sys.argv[1]
    reminders = ['15055667788']  # 特殊提醒要查看的人,就是@某人一下
    url = 此处填写上面webhook的内容
    print(send_msg(url, reminders, msg))

步骤三:测试脚本执行

[root@ localhost day12]# python3 dingtalk.py "这只是一个测试而已"

/

图-12

 

5 案例5:获取zabbix版本信息

5.1 问题

编写一个zabbix_apiversion.py脚本,实现以下功能:

  1. 安装zabbix服务器
  2. 获取zabbix api的url
  3. 编写python程序,访问zabbix api,取得zabbix版本号

5.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:安装zabbix服务器

安装zabbix服务器具体步骤请参照NSD SECURITY DAY06 cookbook中案例2操作

步骤二:获取zabbix api的url

1)设置前端后,你就可以使用远程HTTP请求来调用API。为此,需要向api_jsonrpc.php位于前端目录中的文件发送HTTP POST请求。如果你的Zabbix前端安装在http://192.168.4.2/zabbix,那么用HTTP请求来调用apiinfo.version方法就如下面这样:

POST 192.168.4.2/zabbix/api_jsonrpc.php HTTP/1.1

2)从zabbix官方文档中获取 Zabbix API 版本,如图-7所示:

官方文档地址如下:

https://www.zabbix.com/documentation/3.4/zh/manual/api/reference/apiinfo/version

图-13

步骤三:编写脚本

在HTTP协议中,post提交的数据必须放在消息主体中,但是协议中并没有规定必须使用什么编码方式,从而导致了提交方式的不同。服务端根据请求头中的Content-Type字段来获知请求中的消息主体是用何种方式进行编码,再对消息主体进行解析。

请求的 Content-Type 头部必须设置为以下值之一:

application/json-rpc

application/json

application/jsonrequest

[root@localhost day12]# vim zabbix_apiversion.py
#!/usr/bin/env python3

import requests
import json	# python中的dict类型要转换为json格式的数据需要用到json库

#要访问的网址
url = 'http://192.168.4.2/zabbix/api_jsonrpc.php'
#请求头部信息
headers = {'Content-Type': 'application/json-rpc'}
# data是从官方文档处获得的
data = {
    "jsonrpc": "2.0",	#jsonrpc协议的版本号,固定的
    "method": "apiinfo.version",		#在zabbix手册上查到的,查询zabbix版本
    "params": [],		#没有额外参数
    "id": 1	#随便写个数字
}

#使用requests发送请求,访问指定网站,向url发送data请求,r收到的返回响应为json格式
#将data转成json格式,zabbix要求提交的数据是json格式
r = requests.post(url, headers=headers, data=json.dumps(data))
#将json格式解码,zabbix返回的数据都是json格式
print(r.json()))

需要注意的是python中并没有json类型这一说法,通过json.dumps(data)转换的字典对象,最后得到的是一个字符串对象,也就是说,在python中json格式的数据实际上就是一个字符串

步骤四:测试脚本执行

[root@localhost day12]# python3 zabbix_apiversion.py
{"jsonrpc": "2.0", "result": "2.4.0", "id": 1}

6 案例6:获取令牌

6.1 问题

编写一个get_token.py脚本,实现以下功能:

  1. 编写get_token函数
  2. 该函数接受zabbix服务器url、用户名和密码作为参数
  3. 函数返回值为用户令牌token

6.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:编写脚本get_token.py,获取身份令牌

1)从zabbix官方文档中使用 user.login 方法登录并获取身份验证令牌请求,如图-8所示:

官方文档地址如下:

https://www.zabbix.com/documentation/3.4/zh/manual/api/reference/user/login

图-14

2)编写get_token.py文件

[root@localhost day12]# vim get_token.py
#!/usr/bin/env python3

import requests
import json	# python中的dict类型要转换为json格式的数据需要用到json库

#要访问的网址
url = 'http://192.168.4.2/zabbix/api_jsonrpc.php'
#请求头部信息
headers = {'Content-Type': 'application/json-rpc'}
# data是从官方文档处获得的
data = {
# API使用的JSON-RPC协议的版本; Zabbix API实现JSON-RPC版本2.0
    "jsonrpc": "2.0",
    "method": "user.login",	#调用的API方法
# params将被传递给API方法的参数
    "params": {
        "user": "Admin",
        "password": "zabbix"
    },
    "id": 1	#请求的任意标识符
}
#使用requests发送请求,访问指定网站,向url发送data请求,r收到的返回响应为json格式
#将data转成json格式
r = requests.post(url, headers=headers, data=json.dumps(data))
#将json格式解码
print(r.json()))

步骤四:测试脚本执行,获取用户令牌token

[root@localhost day12]# python3 get_token.py 
{"jsonrpc": "2.0", "result": "0424bd59b807674191e7d77572075f33", "id": 1}

7 案例7:创建主机

7.1 问题

编写一个remote_comm.py脚本,实现以下功能:

  1. 主机192.168.4.10已安装zabbix_agent
  2. 将该主机填加到zabbix监控的主机中
  3. 主机属于Linux Servers组

7.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:编写脚本,检索组

1)从zabbix官方文档中使用hostgroup.get 方法获取主机组请求,如图-9所示:

官方文档地址如下:

https://www.zabbix.com/documentation/3.4/zh/manual/api/reference/hostgroup/get

图-15

2)编写get_hostgroup.py文件,检索组

[root@localhost day12]# vim get_hostgroup.py
#!/usr/bin/env python3

import requests
import json	# python中的dict类型要转换为json格式的数据需要用到json库

#要访问的网址
url = 'http://192.168.4.2/zabbix/api_jsonrpc.php'
#请求头部信息
headers = {'Content-Type': 'application/json-rpc'}
# data是从官方文档处获得的
data = {
# API使用的JSON-RPC协议的版本; Zabbix API实现JSON-RPC版本2.0
    "jsonrpc": "2.0",
    "method": " hostgroup.get ",	#调用的API方法
# params将被传递给API方法的参数
     "params": {
         "output": "extend",
     },
     "auth": "0424bd59b807674191e7d77572075f33",	#之前获取到的令牌
    "id": 1	#请求的任意标识符
}
#使用requests发送请求,访问指定网站,向url发送data请求,r收到的返回响应为json格式
#将data转成json格式
r = requests.post(url, headers=headers, data=json.dumps(data))
ginfo = r.json()
print(ginfo['result'])	#打印主机组信息
for item in ginfo['result']:
    print(item['groupid'], item['name'])	#打印主机组id和名称

3)测试脚本执行,获取了主机名称及id,如图-10所示:

图-16

步骤二:编写脚本,检索模板

1)从zabbix官方文档中使用template.get 方法获取模板请求,如图-11所示:

官方文档地址如下:

https://www.zabbix.com/documentation/3.4/zh/manual/api/reference/template/get

图-17

2)编写get_template.py文件

[root@localhost day12]# vim get_template.py
#!/usr/bin/env python3

import requests
import json	# python中的dict类型要转换为json格式的数据需要用到json库

#要访问的网址
url = 'http://192.168.4.2/zabbix/api_jsonrpc.php'
#请求头部信息
headers = {'Content-Type': 'application/json-rpc'}
# data是从官方文档处获得的
data = {
# API使用的JSON-RPC协议的版本; Zabbix API实现JSON-RPC版本2.0
    "jsonrpc": "2.0",
    "method": "template.get",	#调用的API方法
# params将被传递给API方法的参数
      "params": {
         "output": "extend",
     },
     "auth": "0424bd59b807674191e7d77572075f33",	#之前获取到的令牌
    "id": 1	#请求的任意标识符
}
#使用requests发送请求,访问指定网站,向url发送data请求,r收到的返回响应为json格式
#将data转成json格式
r = requests.post(url, headers=headers, data=json.dumps(data))
#将json格式解码
tinfo = r.json()
#print(tinfo)		#打印模板信息
for item in tinfo['result']:
    print(item['templateid'], item['host'])		#打印模板名及id

3)测试脚本执行,获取了模板名称及id,如图-12所示:

图-18

步骤三:编写脚本,创建主机

1)从zabbix官方文档中使用host.create方法获取创建主机请求,如图-13所示:

官方文档地址如下:

https://www.zabbix.com/documentation/3.4/zh/manual/api/reference/host/create

图-19

2)编写get_host.py文件

[root@localhost day12]# vim get_host.py
#!/usr/bin/env python3

import requests
import json	# python中的dict类型要转换为json格式的数据需要用到json库

#要访问的网址
url = 'http://192.168.4.2/zabbix/api_jsonrpc.php'
#请求头部信息
headers = {'Content-Type': 'application/json-rpc'}
# data是从官方文档处获得的
data = {
# API使用的JSON-RPC协议的版本; Zabbix API实现JSON-RPC版本2.0
    "jsonrpc": "2.0",
    "method": "user.login",	#调用的API方法
# params将被传递给API方法的参数
    "params": {
        "host": "mylinux",		#要创建的主机的名称
        "interfaces": [
            {
                "type": 1,  # 1 agent; 2 SNMP; 3 IPMI; 4 JMX
                "main": 1,  # 该接口是否在主机上用作默认接口。1 默认
                "useip": 1,  # 是否应通过IP进行连接
                "ip": "192.168.4.3",		
                "dns": "",
                "port": "10050"		#ip已装zabbix_agent,端口号为10050
            }
        ],
        "groups": [
            {
                "groupid": "2"		#之前检索到的主机组id
            }
        ],
        "templates": [
            {
                "templateid": "10001"		#之前检索到的模板id
            }
        ],
        "inventory_mode": 0,		#资产信息,0为停用
    },
    "auth": "0424bd59b807674191e7d77572075f33",		#之前获取到的令牌
    "id": 1	#请求的任意标识符
}
#使用requests发送请求,访问指定网站,向url发送data请求,r收到的返回响应为json格式
#将data转成json格式
r = requests.post(url, headers=headers, data=json.dumps(data))

3)测试脚本执行,运行脚本成功后,主机创建成功,如图-20所示:

图-20

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为了减轻多服务器配置和操作工作量以及安全性,特研究此课题,理论上可以同步所有想同步的文件,并且做到一键操作,不需要切换用户,不需要多次操作脚本,中途不需要输入任何字。 1, hosts文件 2, play.yml文件 剧本文件,按标准放到tasks文件夹内,因后面脚本写了路径,如果不愿意放tasks文件夹,需要改后面sh脚本路径参数 3, rsync_notice.py文件 钉钉机器人发送消息文件,此文件放在tools文件夹内,会调用备份日志进行分析,过滤后,发送到钉钉群内。各位同事可修改文件里的Webhoo为自己的机器人key 4, deploy.sh 文件 调用py钉钉文件发消息,并且处理备份日志,删除近期日志等后续事宜,请放在tools文件夹内 1.3.3. 功能基本介绍 1, 在对应脚本里基本都有注释,这里简单介绍下 2, 剧本文件需要在主控机器(备份机器),root用户下运行,运行一次即可,后续sh及py脚本会自动处理。一键搞定所有事情,中途无需手动干预; 3, 自行修改host文件为自己项目地址,bak为备份文件服务器,为安全起见,hosts文件进行了vault加密,密码123456,运行剧本文件,请加—ask-vault-pass 4, 再次提醒,在脚本运行完成后,为保险起见,可将hosts文件中的root密码删除,或修改复杂密码,不会影响后续同步功能。 5, 剧本流程介绍: 1) 主控被控端安装rsync及相关依赖软件; 2) 主控与被控端添加备份用户,rsync; 3) 主控端即备份服务器建立备份文件夹,设置归属用户; 4) 主控及被控端自动切换rsync用户,使用rsync用户配置免密访问所有被控端,即便服务器被黑,rsync用户访问也做不了什么; 5) 主控端即备份服务器使用rsync用户增加同步、日志记录、钉钉发送消息等定时任务; 6) 定时任务里各个需要同步的源地址及项目名称,请自行修改; 7) 日志为叠加记录,钉钉消息发完后,会按日期进行备份,同时删除原日志,因为钉钉消息每天都发,避免冗余数据; 6, 钉钉消息脚本介绍: 1) 访问实时备份日志,考虑到钉钉消息,只需要知道同步是否成功,其余数据不关心,所以读取后,进行数据处理,取出服务器地址、成功标识,或未成功标识; 2) 调用钉钉机器人接口,采取markdown形式,此形式可以定义一个固定的标题,比如:rsync同步情况汇总,这样在钉钉机器人安全设置里,只需要将标题设为关键字即可,具体发送内容千奇百怪也没关系。另外两种方式各有弊端,未研究。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值