在已有系统中嵌入grafana仪表盘作数据展示,需要对界面进行二次开发满足风格统一,同时需要对grafana的权限部分进行修改,满足页面进行无缝跳转,同时识别当前用户。
grafana 依赖于nodejs、go、git等,其安装过程略过。
grafana下载后,我选择了v7.0.0 tag分支进行开发。
如果是在window上面进行环境搭建,还需要安装GCC环境。
这里我使用的是minGW64, 这里要根据操作系统选择安装,我选择安装64位。
安装过程可以参考这里
go get 安装速度慢。
yarn install 报错gyp ERR! configure error
yarn install --pure-lockfile --unsafe-perm
yarn 切换镜像源,提高下载速度。
yarn config set registry ‘https://registry.npm.taobao.org’
或
npm config set registry https://registry.npm.taobao.org
也可以使用cnpm:
npm install -g cnpm --registry=https://registry.npm.taobao.org
使用Unknwon/bra 启动grafana
在$GOPATH\src\golang.org\x(需要自己建目录)执行:
git clone https://github.com/golang/sync.git --depth 1
(depth用于指定克隆深度,为1即表示只克隆最近一次commit)
go get github.com/Unknwon/bra(也可以建好目录后,git clone)。
这里成功后没有任何反应,检查到$GOPATH\src\github.com\Unknwon\bra目录生成后,可以停掉命令。
go run bra.go init 初始化
go run bra.go run 编译bra
在前后端都构建成功后,在grafana目录下执行bra run
可以成功运行grafana, 并且文件修改自动发布。
grafana 打包
window下执行go run build.go build package 生成.exe可执行文件。
linux下执行go run build.go build package 后会生成deb、rpm、tar.gz三个版本的压缩包。
打包为deb、rpm需要安装fpm
yum -y install ruby rubygems ruby-devel
gem sources -a http://gems.ruby-china.com/ //原 http://ruby.taobao.org/ 已停止维护
gem sources --remove http://rubygems.org/
gem install fpm
这里比较复杂,我只成功打包了deb, tar.gz。 打包rpm过程中报错。
因为tar.gz已经可以满足要求,这里没有过多研究。
打包一次接近20分钟,需耐心等待。
为了实现跳转过程中不弹出grafana的登录窗口,可以使用匿名登录配置。
#################################### Anonymous Auth ######################
[auth.anonymous]
# enable anonymous access
;enabled = true
# specify organization name that should be used for unauthenticated users
;org_name = Main Org.
# specify role for unauthenticated users
;org_role = Viewer
将";enabled = true"中的分号删除,则配置生效。
这样所有的报表页面访问都不需要登录验证。当然整合oauth2的话,这个配置就不用开启了。
grafana中支持多种第三方登录验证。
#################################### Generic OAuth ##########################
[auth.generic_oauth]
enabled = true
name = OAuth
allow_sign_up = true
client_id = grafana
client_secret = xxxxxx
scopes = server
;email_attribute_name = email:primary
;email_attribute_path =
auth_url = http://xxxxxx:8083/oauth/authorize
token_url = http://xxxxxx:8083/oauth/token
api_url = http://xxxxxxx:8083/oauth/check_token
;allowed_domains =
;team_ids =
;allowed_organizations =
;role_attribute_path =
;tls_skip_verify_insecure = false
;tls_client_cert =
;tls_client_key =
;tls_client_ca =
需要根据具体情况调整参数。
#################################### Server ####################################
[server]
# Protocol (http, https, h2, socket)
;protocol = http
# The ip address to bind to, empty will bind to all interfaces
;http_addr =
# The http port to use
http_port = 8000
# The public facing domain name used to access grafana from a browser
domain = 172.20.4.250
http_port默认为3000,但是在window下端口可能冲突。
domain为局域网ip:避免其他主机访问时,localhost路由不到。
#################################### Security ####################################
[security]
# disable creation of admin user on first start of grafana
;disable_initial_admin_creation = false
# set cookie SameSite attribute. defaults to `lax`. can be set to "lax", "strict", "none" and "disabled"
cookie_samesite = disabled
# set to true if you want to allow browsers to render Grafana in a ,
cookie_samesite = disabled
allow_embedding = true
r.Get("/logout", hs.Logout)
r.Post("/login", quota("session"), bind(dtos.LoginCommand{}), Wrap(hs.LoginPost))
r.Get("/login/:name", quota("session"), hs.OAuthLogin)
r.Get("/login", hs.LoginView)
r.Get("/invite/:code", hs.Index)
由于使用generic_oauth,登录的url为/login/generic_oauth,所以跳转到了hs.OAuthLogin, 在pkg/api/login_oauth.go中处理。
extUser := &models.ExternalUserInfo{
AuthModule: "oauth_" + name,
OAuthToken: token,
AuthId: userInfo.Id,
Name: userInfo.Name,
Login: userInfo.Login,
Email: userInfo.Email,
OrgRoles: map[int64]models.RoleType{},
Groups: userInfo.Groups,
}
源码从token中获取到用户信息,但是我们的认证中心用户信息是以json格式存放在token中的。
// 从token拿到user的json对象
user := token.Extra("user")
// 将json对象转成map
userInfo, ok := user.(map[string]interface{})
// 获取对象属性
userInfo["nickName"]
extUser := &models.ExternalUserInfo{
AuthModule: "oauth_" + name,
OAuthToken: token,
AuthId: fmt.Sprintf("%s", userInfo["id"]),
Name: fmt.Sprintf("%s", userInfo["nickName"]),
Login: fmt.Sprintf("%s", userInfo["username"]),
Email: fmt.Sprintf("%s", userInfo["email"]),
OrgRoles: map[int64]models.RoleType{},
//Groups: groups,
}
将token中的用户信息重新填入grafana框架中。这样登录后,便可以拿到用户信息。