Merge pull request #683 from alibaba/develop

Release 0.8
This commit is contained in:
yanlinly 2019-01-22 22:29:05 +08:00 committed by GitHub
commit ffb8720820
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 309 additions and 143 deletions

3
.gitattributes vendored Normal file
View File

@ -0,0 +1,3 @@
*.js linguist-language=java
*.css linguist-language=java
*.html linguist-language=java

View File

@ -16,7 +16,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>0.8.0-SNAPSHOT</version>
<version>0.8.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -34,8 +34,6 @@ public class NacosException extends Exception {
public NacosException() {
}
;
public NacosException(int errCode, String errMsg) {
this.errCode = errCode;
this.errMsg = errMsg;

View File

@ -16,7 +16,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>0.8.0-SNAPSHOT</version>
<version>0.8.0</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -18,7 +18,7 @@
<parent>
<artifactId>nacos-all</artifactId>
<groupId>com.alibaba.nacos</groupId>
<version>0.8.0-SNAPSHOT</version>
<version>0.8.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>0.8.0-SNAPSHOT</version>
<version>0.8.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -33,7 +33,7 @@ public class HttpMethod {
public static final String DELETE = "DELETE";
public static final String OPTIONS = "PATCH";
public static final String OPTIONS = "OPTIONS";
public static final String TRACE = "TRACE";
}

View File

@ -17,7 +17,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>0.8.0-SNAPSHOT</version>
<version>0.8.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -36,8 +36,6 @@ public class ConfigKey implements Serializable {
public ConfigKey() {
}
;
public ConfigKey(String appName, String dataId, String group) {
this.appName = appName;
this.dataId = dataId;

View File

@ -189,6 +189,6 @@ CREATE TABLE roles (
role varchar(50) NOT NULL
);
INSERT INTO users (username, password, enabled) VALUES ('admin', '$2a$10$HxtJtd59imujvbux.i55zOGewhnJiLVXX8D9AETDMV.XtBLDGOXtW', TRUE);
INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);
INSERT INTO roles (username, role) VALUES ('admin', 'ROLE_ADMIN');
INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');

View File

@ -184,6 +184,6 @@ CREATE TABLE roles (
role varchar(50) NOT NULL
);
INSERT INTO users (username, password, enabled) VALUES ('admin', '$2a$10$HxtJtd59imujvbux.i55zOGewhnJiLVXX8D9AETDMV.XtBLDGOXtW', TRUE);
INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);
INSERT INTO roles (username, role) VALUES ('admin', 'ROLE_ADMIN');
INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>0.8.0-SNAPSHOT</version>
<version>0.8.0</version>
</parent>
<artifactId>nacos-console</artifactId>
<!--<packaging>war</packaging>-->

View File

@ -47,7 +47,7 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
String jwt = resolveToken(request);
if (!StringUtils.isEmpty(jwt.trim()) && SecurityContextHolder.getContext().getAuthentication() == null) {
if (jwt != null && !"".equals(jwt.trim()) && SecurityContextHolder.getContext().getAuthentication() == null) {
if (this.tokenProvider.validateToken(jwt)) {
/**
* get auth info

View File

@ -0,0 +1,30 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.console.utils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
/**
* Password encoder tool
*
* @author nacos
*/
public class PasswordEncoderUtil {
public static void main(String[] args) {
System.out.println(new BCryptPasswordEncoder().encode("nacos"));
}
}

View File

@ -35,6 +35,8 @@ nacos.cmdb.eventTaskInterval=10
nacos.cmdb.labelTaskInterval=300
nacos.cmdb.loadDataAtStart=false
#management.endpoints.web.exposure.include=*
db.num=2
db.url.0=jdbc:mysql://11.162.196.161:3306/diamond_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.url.1=jdbc:mysql://11.163.152.91:3306/diamond_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
@ -45,4 +47,4 @@ db.password=4b9622f3f70c7677835ac5a6719e7caf
#management.security=false
#security.basic.enabled=false
#nacos.security.ignore.urls=/**
nacos.security.ignore.urls=/,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/login,/v1/console/health,/v1/cs/**,/v1/ns/**,/v1/cmdb/**
nacos.security.ignore.urls=/,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/login,/v1/console/health,/v1/cs/**,/v1/ns/**,/v1/cmdb/**,/actuator/**

View File

@ -184,6 +184,6 @@ CREATE TABLE roles (
role varchar(50) NOT NULL
);
INSERT INTO users (username, password, enabled) VALUES ('admin', '$2a$10$HxtJtd59imujvbux.i55zOGewhnJiLVXX8D9AETDMV.XtBLDGOXtW', TRUE);
INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);
INSERT INTO roles (username, role) VALUES ('admin', 'ROLE_ADMIN');
INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');

View File

@ -12,6 +12,7 @@
"no-template-curly-in-string": "off",
"no-unused-vars": "off",
"no-tabs": "off",
"no-param-reassign": "off",
"react/no-string-refs": "off",
"react/no-unused-state": "off",
"no-return-assign": "off",
@ -29,6 +30,6 @@
"generator-star-spacing": "off",
"wrap-iife": "off",
"arrow-parens": "off",
"indent": "off",
"indent": "off"
}
}

View File

@ -64,7 +64,7 @@
"webpack-dev-server": "^3.1.13"
},
"dependencies": {
"@alifd/next": "^1.11.5",
"@alifd/next": "^1.11.10",
"axios": "^0.18.0",
"jquery": "^3.3.1",
"moment": "^2.23.0",

View File

@ -323,7 +323,6 @@ select,
textarea {
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
a {

View File

@ -20,7 +20,7 @@
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Nacos</title>
<link rel="shortcut icon" href="//www.aliyun.com/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="css/bootstrap.css">
<link rel="stylesheet" type="text/css" href="css/bootstrap.css">
<link rel="stylesheet" type="text/css" href="css/console1412.css">
<!-- 第三方css开始 -->
<link rel="stylesheet" type="text/css" href="css/codemirror.css">

View File

@ -194,7 +194,7 @@ class EditorNameSpace extends React.Component {
<Input
{...this.field.init('namespaceDesc', {
rules: [
{ required: true, message: locale.namespace },
{ required: true, message: locale.namespaceDesc },
{ validator: this.validateChart.bind(this) },
],
})}

View File

@ -213,7 +213,7 @@ class NewNameSpace extends React.Component {
rules: [
{
required: true,
message: locale.namespacenotnull,
message: locale.namespacedescnotnull,
},
{ validator: this.validateChart.bind(this) },
],

View File

@ -114,7 +114,6 @@ class App extends React.Component {
<HashRouter>
<Switch>
<Route path="/login" component={Login} />
<Layout navList={_menu.data}>
{MENU.map(item => (
<Route key={item.path} {...item} />

View File

@ -32,6 +32,8 @@ class Header extends React.Component {
static propTypes = {
locale: PropTypes.object,
history: PropTypes.object,
location: PropTypes.object,
language: PropTypes.string,
changeLanguage: PropTypes.func,
};
@ -53,7 +55,6 @@ class Header extends React.Component {
const base64Url = token.split('.')[1];
const base64 = base64Url.replace('-', '+').replace('_', '/');
const parsedToken = JSON.parse(window.atob(base64));
console.log(parsedToken);
return parsedToken.sub;
}
return '';

View File

@ -20,6 +20,8 @@ import $ from 'jquery';
import { setParams } from '../globalLib';
import { connect } from 'react-redux';
import './index.scss';
@withRouter
@connect(state => ({ ...state.locale }))
@ConfigProvider.config
@ -29,6 +31,7 @@ class MainLayout extends React.Component {
static propTypes = {
navList: PropTypes.array,
history: PropTypes.object,
location: PropTypes.object,
locale: PropTypes.object,
children: PropTypes.any,
};
@ -72,6 +75,11 @@ class MainLayout extends React.Component {
iconClass.className = tmpClassName;
}
/**
* Click the back button
* TODO: this.props.history.goBack(); ???
* @param url
*/
nacosGoBack(url) {
const params = window.location.hash.split('?')[1];
const urlArr = params.split('&') || [];
@ -91,6 +99,9 @@ class MainLayout extends React.Component {
}
}
}
if (localStorage.getItem('namespace')) {
queryParams.push(`namespace=${localStorage.getItem('namespace')}`);
}
this.props.history.push(`/${url}?${queryParams.join('&')}`);
}
@ -201,7 +212,8 @@ class MainLayout extends React.Component {
}
nacosLoopNav(data, _index = 0, parent) {
const { locale = {} } = this.props;
const { locale = {}, location = {} } = this.props;
const { pathname } = location;
let index = _index;
// 遍历导航只显示2级
const self = this;
@ -238,6 +250,7 @@ class MainLayout extends React.Component {
} else {
return (
<li
className={pathname === `/${item.serviceName}` ? 'selected' : ''}
key={`${item.serviceName}`}
data-spm-click={`gostr=/aliyun;locaid=${item.serviceName}`}
onClick={this.navTo.bind(this, `/${item.serviceName}`)}
@ -256,6 +269,7 @@ class MainLayout extends React.Component {
}
return (
<li
className={pathname === `/${item.serviceName}` ? 'selected' : ''}
key={`${item.serviceName}`}
data-spm-click={`gostr=/aliyun;locaid=${item.serviceName}`}
onClick={this.navTo.bind(this, `/${item.serviceName}`)}
@ -396,7 +410,6 @@ class MainLayout extends React.Component {
<span style={{ marginLeft: 5 }}>{nacosVersion}</span>
</div>
)}
<div
className="product-nav-list"
style={{ position: 'relative', top: 0, height: '100%' }}

View File

@ -1394,3 +1394,7 @@ h6 {
padding-right: 20px;
}
}
.product-nav-list li.selected a {
background-color: #F4F6F8;
}

View File

@ -125,6 +125,9 @@ const I18N_CONF = {
healthCheckPatternService: 'Service',
healthCheckPatternClient: 'Client',
healthCheckPatternNone: 'None',
serviceNameRequired: 'Please enter a service name',
protectThresholdRequired: 'Please enter a protect threshold',
healthCheckModeRequired: 'Please select health check pattern',
},
InstanceTable: {
operation: 'Operation',
@ -312,6 +315,7 @@ const I18N_CONF = {
editNamespace: 'Loading...',
load: 'Namespace:',
namespace: 'Namespace cannot be empty',
namespaceDesc: 'Namespace description cannot be empty',
description: 'Description:',
},
ExportDialog: {
@ -366,6 +370,7 @@ const I18N_CONF = {
loading: 'Loading...',
name: 'Namespace:',
namespacenotnull: 'Namespace cannot be empty',
namespacedescnotnull: 'Namespace description cannot be empty',
description: 'Description:',
},
NameSpaceList: {

View File

@ -125,6 +125,9 @@ const I18N_CONF = {
healthCheckPatternService: '服务端',
healthCheckPatternClient: '客户端',
healthCheckPatternNone: '禁止',
serviceNameRequired: '请输入服务名',
protectThresholdRequired: '请输入保护阈值',
healthCheckModeRequired: '请选择健康检查模式',
},
InstanceTable: {
operation: '操作',
@ -311,6 +314,7 @@ const I18N_CONF = {
editNamespace: '加载中...',
load: '命名空间名',
namespace: '命名空间不能为空',
namespaceDesc: '命名空间描述不能为空',
description: '描述',
},
ExportDialog: {
@ -365,6 +369,7 @@ const I18N_CONF = {
loading: '加载中...',
name: '命名空间名',
namespacenotnull: '命名空间不能为空',
namespacedescnotnull: '命名空间描述不能为空',
description: '描述',
},
NameSpaceList: {

View File

@ -734,7 +734,7 @@ class ConfigurationManagement extends React.Component {
style={{
position: 'relative',
marginTop: 10,
height: this.state.isAdvancedQuery ? 'auto' : 48,
height: this.state.isAdvancedQuery ? 'auto' : 42,
overflow: 'hidden',
}}
>

View File

@ -433,8 +433,8 @@ class NewConfig extends React.Component {
color={'#333'}
>
<h1>{locale.newListing}</h1>
<Form field={this.field}>
<FormItem label={'Data ID:'} required {...formItemLayout}>
<Form className="new-config-form" field={this.field} {...formItemLayout}>
<FormItem label={'Data ID:'} required>
<Input
{...init('dataId', {
rules: [
@ -442,13 +442,10 @@ class NewConfig extends React.Component {
required: true,
message: locale.newConfig,
},
{
max: 255,
message: locale.dataIdIsNotEmpty,
},
{ validator: this.validateChart.bind(this) },
],
})}
maxLength={255}
addonTextBefore={
this.state.addonBefore ? (
<div style={{ minWidth: 100, color: '#373D41' }}>{this.state.addonBefore}</div>
@ -456,7 +453,7 @@ class NewConfig extends React.Component {
}
/>
</FormItem>
<FormItem label={'Group:'} required {...formItemLayout}>
<FormItem label={'Group:'} required>
<Combobox
style={{ width: '100%' }}
size={'large'}
@ -483,49 +480,52 @@ class NewConfig extends React.Component {
</FormItem>
<FormItem
label={' '}
{...formItemLayout}
style={{ display: this.state.showGroupWarning ? 'block' : 'none' }}
>
<Message type={'warning'} size={'medium'} animation={false}>
{locale.annotation}
</Message>
</FormItem>
<FormItem label={''} {...formItemLayout}>
<div>
<FormItem
label={locale.tags}
className={`more-item${!this.state.showmore ? ' hide' : ''}`}
>
<Select
size={'medium'}
hasArrow
style={{ width: '100%', height: '100%!important' }}
autoWidth
multiple
mode="tag"
filterLocal
placeholder={locale.pleaseEnterTag}
dataSource={this.state.tagLst}
value={this.state.config_tags}
onChange={this.setConfigTags.bind(this)}
hasClear
/>
</FormItem>
<FormItem
label={locale.groupIdCannotBeLonger}
className={`more-item${!this.state.showmore ? ' hide' : ''}`}
>
<Input {...init('appName')} readOnly={this.inApp} />
</FormItem>
<FormItem label=" ">
<div className="more-container">
<a style={{ fontSize: '12px' }} onClick={this.toggleMore.bind(this)}>
{this.state.showmore ? locale.dataIdLength : locale.collapse}
</a>
</div>
</FormItem>
<div style={{ overflow: 'hidden', height: this.state.showmore ? 'auto' : '0' }}>
<FormItem label={locale.tags} {...formItemLayout}>
<Select
size={'medium'}
hasArrow
style={{ width: '100%', height: '100%!important' }}
autoWidth
multiple
mode="tag"
filterLocal
placeholder={locale.pleaseEnterTag}
dataSource={this.state.tagLst}
value={this.state.config_tags}
onChange={this.setConfigTags.bind(this)}
hasClear
/>
</FormItem>
<FormItem label={locale.groupIdCannotBeLonger} {...formItemLayout}>
<Input {...init('appName')} readOnly={this.inApp} />
</FormItem>
</div>
<FormItem label={locale.description} {...formItemLayout}>
<FormItem label={locale.description}>
<Input.TextArea htmlType={'text'} multiple rows={3} {...init('desc')} />
</FormItem>
<FormItem label={locale.targetEnvironment} {...formItemLayout}>
<FormItem label={locale.targetEnvironment}>
<RadioGroup
dataSource={list}
value={this.state.configType}
@ -543,9 +543,8 @@ class NewConfig extends React.Component {
size={'small'}
style={{
color: '#1DC11D',
marginRight: 5,
margin: '0 5px',
verticalAlign: 'middle',
marginTop: 2,
}}
/>
}
@ -560,12 +559,11 @@ class NewConfig extends React.Component {
</span>
}
required
{...formItemLayout}
>
<div id={'container'} style={{ width: '100%', height: 300 }} />
</FormItem>
<FormItem {...formItemLayout} label={''}>
<FormItem label=" ">
<div style={{ textAlign: 'right' }}>
<Button
type={'primary'}

View File

@ -10,3 +10,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.new-config-form {
margin-top: 36px;
}
.more-item.hide {
display: none;
}

View File

@ -5,6 +5,7 @@ import { withRouter } from 'react-router-dom';
import './index.scss';
import Header from '../../layouts/Header';
import { request } from '../../globalLib';
import PropTypes from 'prop-types';
const FormItem = Form.Item;
@ -13,6 +14,11 @@ const FormItem = Form.Item;
class Login extends React.Component {
static displayName = 'Login';
static propTypes = {
locale: PropTypes.object,
history: PropTypes.object,
};
constructor(props) {
super(props);
this.field = new Field(this);
@ -28,15 +34,14 @@ class Login extends React.Component {
type: 'post',
url: 'v1/auth/login',
data: values,
success: res => {
if (res.code === 200) {
const data = res.data;
success: ({ code, data }) => {
if (code === 200) {
// TODO: token
localStorage.setItem('token', data);
// TODO: 使react router
this.props.history.push('/');
}
if (res.code === 401) {
if (code === 401) {
Message.error({
content: locale.invalidUsernameOrPassword,
});

View File

@ -26,6 +26,7 @@ $contentWidth: 1280px;
width: 480px;
height: 540px;
top: 90px;
border: 0px;
input,
input::-webkit-input-placeholder {
font-size: 16px;
@ -49,6 +50,7 @@ $contentWidth: 1280px;
font-size: 16px;
background: #4190ff 100%;
color: white;
border: 0px;
}
}
}
@ -88,6 +90,7 @@ $contentWidth: 1280px;
position: absolute;
left: 0;
top: 50%;
margin-top: -47px;
transform: translateY(-50%);
}
.product-area {

View File

@ -33,6 +33,7 @@ class EditServiceDialog extends React.Component {
isCreate: false,
editService: {},
editServiceDialogVisible: false,
errors: { name: {}, protectThreshold: {}, healthCheckMode: {} },
};
this.show = this.show.bind(this);
}
@ -52,10 +53,32 @@ class EditServiceDialog extends React.Component {
this.setState({ editServiceDialogVisible: false });
}
validator(field) {
const { locale = {} } = this.props;
const errors = Object.assign({}, this.state.errors);
const helpMap = {
name: locale.serviceNameRequired,
protectThreshold: locale.protectThresholdRequired,
healthCheckMode: locale.healthCheckModeRequired,
};
if (field.protectThreshold === 0) {
field.protectThreshold = '0';
}
for (const key in field) {
if (!field[key]) {
errors[key] = { validateState: 'error', help: helpMap[key] };
this.setState({ errors });
return false;
}
}
return true;
}
onConfirm() {
const { isCreate } = this.state;
const editService = Object.assign({}, this.state.editService);
const { name, protectThreshold, healthCheckMode, metadataText, selector } = editService;
if (!this.validator({ name, protectThreshold, healthCheckMode })) return;
request({
method: isCreate ? 'POST' : 'PUT',
url: 'v1/ns/service',
@ -86,7 +109,15 @@ class EditServiceDialog extends React.Component {
}
onChangeCluster(changeVal) {
const resetKey = ['name', 'protectThreshold', 'healthCheckMode'];
const { editService = {} } = this.state;
const errors = Object.assign({}, this.state.errors);
resetKey.forEach(key => {
if (changeVal[key]) {
errors[key] = {};
this.setState({ errors });
}
});
this.setState({
editService: Object.assign({}, editService, changeVal),
});
@ -99,7 +130,7 @@ class EditServiceDialog extends React.Component {
render() {
const { locale = {} } = this.props;
const { isCreate, editService, editServiceDialogVisible } = this.state;
const { isCreate, editService, editServiceDialogVisible, errors } = this.state;
const {
name,
protectThreshold,
@ -118,20 +149,35 @@ class EditServiceDialog extends React.Component {
onClose={() => this.hide()}
>
<Form {...DIALOG_FORM_LAYOUT}>
<Form.Item label={`${locale.serviceName}:`} {...formItemLayout}>
<Form.Item
required={isCreate}
{...formItemLayout}
label={`${locale.serviceName}:`}
{...errors.name}
>
{!isCreate ? (
<p>{name}</p>
) : (
<Input value={name} onChange={name => this.onChangeCluster({ name })} />
)}
</Form.Item>
<Form.Item label={`${locale.protectThreshold}:`} {...formItemLayout}>
<Form.Item
required
{...formItemLayout}
label={`${locale.protectThreshold}:`}
{...errors.protectThreshold}
>
<Input
value={protectThreshold}
onChange={protectThreshold => this.onChangeCluster({ protectThreshold })}
/>
</Form.Item>
<Form.Item label={`${locale.healthCheckPattern}:`} {...formItemLayout}>
<Form.Item
required
{...formItemLayout}
label={`${locale.healthCheckPattern}:`}
{...errors.healthCheckMode}
>
<Select
className="full-width"
defaultValue={healthCheckMode}

View File

@ -14,7 +14,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { request } from '@/globalLib';
import { Button, Card, ConfigProvider, Form, Loading } from '@alifd/next';
import { Input, Button, Card, ConfigProvider, Form, Loading } from '@alifd/next';
import EditServiceDialog from './EditServiceDialog';
import EditClusterDialog from './EditClusterDialog';
import InstanceTable from './InstanceTable';
@ -126,25 +126,25 @@ class ServiceDetail extends React.Component {
</Button>
</h1>
<Form style={{ width: '60%' }} {...pageFormLayout}>
<Form {...pageFormLayout}>
<FormItem label={`${locale.serviceName}:`}>
<p>{service.name}</p>
<Input value={service.name} readOnly />
</FormItem>
<FormItem label={`${locale.protectThreshold}:`}>
<p>{service.protectThreshold}</p>
<Input value={service.protectThreshold} readOnly />
</FormItem>
<FormItem label={`${locale.healthCheckPattern}:`}>
<p>{service.healthCheckMode}</p>
<Input value={service.healthCheckMode} readOnly />
</FormItem>
<FormItem label={`${locale.metadata}:`}>
<p>{metadataText}</p>
<Input value={metadataText} readOnly />
</FormItem>
<FormItem label={`${locale.type}:`}>
<p>{selector.type}</p>
<Input value={selector.type} readOnly />
</FormItem>
{service.type === 'label' && (
<FormItem label={`${locale.selector}:`}>
<p>{selector.selector}</p>
<Input value={selector.selector} readOnly />
</FormItem>
)}
</Form>

View File

@ -2,10 +2,10 @@
# yarn lockfile v1
"@alifd/next@^1.11.5":
version "1.11.8"
resolved "https://registry.yarnpkg.com/@alifd/next/-/next-1.11.8.tgz#02b8b6faf3cbfaf2a4edc3c8943fa5a28dbcb546"
integrity sha512-zXxeO35XeAsxxlhZsJbslPeb9gzsUdwlk3bwVQbxI/J7IsfEydsyXUT2/wY4pR6UHyaO2YG4wrgQ1N8YhngwPQ==
"@alifd/next@^1.11.10":
version "1.11.10"
resolved "https://registry.yarnpkg.com/@alifd/next/-/next-1.11.10.tgz#7efddb8154024578fee19d51433d532efbf2c649"
integrity sha512-RkPRGyk2KjUQPJplKqHG2MAhDCzH3bVpq/klXmI1MvQErSEL+hgNSgvqmh3M/vSKVGIai27vs/Xlgju54LRvKA==
dependencies:
babel-runtime "^6.26.0"
classnames "^2.2.3"
@ -1820,9 +1820,9 @@ caniuse-api@^3.0.0:
lodash.uniq "^4.5.0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000928:
version "1.0.30000928"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000928.tgz#805e828dc72b06498e3683a32e61c7507fd67b88"
integrity sha512-aSpMWRXL6ZXNnzm8hgE4QDLibG5pVJ2Ujzsuj3icazlIkxXkPXtL+BWnMx6FBkWmkZgBHGUxPZQvrbRw2ZTxhg==
version "1.0.30000929"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000929.tgz#7b391b781a9c3097ecc39ea053301aea8ea16317"
integrity sha512-n2w1gPQSsYyorSVYqPMqbSaz1w7o9ZC8VhOEGI9T5MfGDzp7sbopQxG6GaQmYsaq13Xfx/mkxJUWC1Dz3oZfzw==
caseless@~0.12.0:
version "0.12.0"
@ -2910,9 +2910,9 @@ eslint-config-ali@^4.1.0:
integrity sha512-vPItHMwM4e8TpXH/owvZCW0V4we7QlxSok2ObeOXwu99Gu26mbdqukH47EUDBrm93ru9HefNlYA7BQ8jrQy1dA==
eslint-config-prettier@^3.3.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-3.4.0.tgz#97dd5bf33d4d85862fdadf2ea89b4d6cebf3ba4f"
integrity sha512-VDBMmnwA1SH4tGoyTVStbjI18xAFtozvrodjEuoqtP/P/XLJs5Ga8sFf7GSSPxAkgh65CGYT/zOXzsf2IA0aqw==
version "3.5.0"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-3.5.0.tgz#fb29575c5be7ed79c1637c5a0c58985833290805"
integrity sha512-LcZEoAY5lL3/H2NTFSeUl/z8X8oMea1IxLEIb5uDbRxPTdQeeT7oGpRWT6UwHXGcoRbYH0TZmfRsh8iXbpyW7A==
dependencies:
get-stdin "^6.0.0"
@ -2967,9 +2967,9 @@ eslint-plugin-prettier@^3.0.0:
prettier-linter-helpers "^1.0.0"
eslint-plugin-react@^7.11.1:
version "7.12.3"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.12.3.tgz#b9ca4cd7cd3f5d927db418a1950366a12d4568fd"
integrity sha512-WTIA3cS8OzkPeCi4KWuPmjR33lgG9r9Y/7RmnLTRw08MZKgAfnK/n3BO4X0S67MPkVLazdfCNT/XWqcDu4BLTA==
version "7.12.4"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.12.4.tgz#b1ecf26479d61aee650da612e425c53a99f48c8c"
integrity sha512-1puHJkXJY+oS1t467MjbqjvX53uQ05HXwjqDgdbGBqf5j9eeydI54G3KwiJmWciQ0HTBacIKw2jgwSBSH3yfgQ==
dependencies:
array-includes "^3.0.3"
doctrine "^2.1.0"
@ -3522,9 +3522,9 @@ fs.realpath@^1.0.0:
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
fsevents@^1.2.2:
version "1.2.4"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426"
integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==
version "1.2.6"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.6.tgz#d3a1864a71876a2eb9b244e3bd8f606eb09568c0"
integrity sha512-BalK54tfK0pMC0jQFb2oHn1nz7JNQD/2ex5pBnCHgBi2xG7VV0cAOGy2RS2VbCqUXx5/6obMrMcQTJ8yjcGzbg==
dependencies:
nan "^2.9.2"
node-pre-gyp "^0.10.0"
@ -4799,9 +4799,9 @@ loader-fs-cache@^1.0.0:
mkdirp "0.5.1"
loader-runner@^2.3.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.1.tgz#026f12fe7c3115992896ac02ba022ba92971b979"
integrity sha512-By6ZFY7ETWOc9RFaAIb23IjJVcM4dvJC/N57nmdz9RSkMXvAXGI7SyVlAw3v8vjtDRlqThgVDVmTnr9fqMlxkw==
version "2.4.0"
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357"
integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==
loader-utils@^0.2.16:
version "0.2.17"
@ -6291,9 +6291,9 @@ postcss-value-parser@^3.0.0, postcss-value-parser@^3.3.0, postcss-value-parser@^
integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==
postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.5, postcss@^7.0.6:
version "7.0.11"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.11.tgz#f63c513b78026d66263bb2ca995bf02e3d1a697d"
integrity sha512-9AXb//5UcjeOEof9T+yPw3XTa5SL207ZOIC/lHYP4mbUTEh4M0rDAQekQpVANCZdwQwKhBtFZCk3i3h3h2hdWg==
version "7.0.13"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.13.tgz#42bf716413e8f1c786ab71dc6e722b3671b16708"
integrity sha512-h8SY6kQTd1wISHWjz+E6cswdhMuyBZRb16pSTv3W4zYZ3/YbyWeJdNUeOXB5IdZqE1U76OUEjjjqsC3z2f3hVg==
dependencies:
chalk "^2.4.2"
source-map "^0.6.1"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>0.8.0-SNAPSHOT</version>
<version>0.8.0</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -25,7 +25,7 @@ set CUSTOM_SEARCH_LOCATIONS=%DEFAULT_SEARCH_LOCATIONS%,file:%BASE_DIR%conf/
if not ""%2"" == "cluster" (
if not "%2" == "cluster" (
set "JAVA_OPT=%JAVA_OPT% -Xms512m -Xmx512m -Xmn256m"
set "JAVA_OPT=%JAVA_OPT% -Dnacos.standalone=true"
) else (

View File

@ -58,11 +58,13 @@ fi
JAVA_MAJOR_VERSION=$($JAVA -version 2>&1 | sed -E -n 's/.* version "([0-9]*).*$/\1/p')
if [[ "$JAVA_MAJOR_VERSION" -ge "9" ]] ; then
JAVA_OPT="${JAVA_OPT} -cp .:${BASE_DIR}/plugins/cmdb/*.jar"
JAVA_OPT="${JAVA_OPT} -Xlog:gc*:file=${BASE_DIR}/logs/nacos_gc.log:time,tags:filecount=10,filesize=102400"
else
JAVA_OPT="${JAVA_OPT} -Djava.ext.dirs=${JAVA_HOME}/jre/lib/ext:${JAVA_HOME}/lib/ext:${BASE_DIR}/plugins/cmdb"
JAVA_OPT="${JAVA_OPT} -Xloggc:${BASE_DIR}/logs/nacos_gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M"
fi
JAVA_OPT="${JAVA_OPT} -Xbootclasspath/a:${BASE_DIR}/plugins/cmdb"
JAVA_OPT="${JAVA_OPT} -Dnacos.home=${BASE_DIR}"
JAVA_OPT="${JAVA_OPT} -jar ${BASE_DIR}/target/nacos-server.jar"
JAVA_OPT="${JAVA_OPT} ${JAVA_OPT_EXT}"

View File

@ -37,4 +37,4 @@ server.tomcat.basedir=
#security.basic.enabled=false
#nacos.security.ignore.urls=/**
nacos.security.ignore.urls=/,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/login,/v1/console/health,/v1/cs/**,/v1/ns/**,/v1/cmdb/**
nacos.security.ignore.urls=/,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/login,/v1/console/health,/v1/cs/**,/v1/ns/**,/v1/cmdb/**,/actuator/**

View File

@ -189,6 +189,6 @@ CREATE TABLE roles (
role varchar(50) NOT NULL
);
INSERT INTO users (username, password, enabled) VALUES ('admin', '$2a$10$HxtJtd59imujvbux.i55zOGewhnJiLVXX8D9AETDMV.XtBLDGOXtW', TRUE);
INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);
INSERT INTO roles (username, role) VALUES ('admin', 'ROLE_ADMIN');
INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');

View File

@ -183,6 +183,6 @@ CREATE TABLE roles (
role varchar(50) NOT NULL
);
INSERT INTO users (username, password, enabled) VALUES ('admin', '$2a$10$HxtJtd59imujvbux.i55zOGewhnJiLVXX8D9AETDMV.XtBLDGOXtW', TRUE);
INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);
INSERT INTO roles (username, role) VALUES ('admin', 'ROLE_ADMIN');
INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>0.8.0-SNAPSHOT</version>
<version>0.8.0</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>0.8.0-SNAPSHOT</version>
<version>0.8.0</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>0.8.0-SNAPSHOT</version>
<version>0.8.0</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -46,7 +46,7 @@ public class ClusterController {
@Autowired
protected DomainsManager domainsManager;
@RequestMapping(value = {"/update", "/add"}, method = RequestMethod.PUT)
@RequestMapping(value = "", method = RequestMethod.PUT)
public String update(HttpServletRequest request) throws Exception {
String namespaceId = WebUtils.optional(request, Constants.REQUEST_PARAM_NAMESPACE_ID,

View File

@ -19,6 +19,7 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.naming.misc.*;
import com.alibaba.nacos.naming.push.PushService;
import com.alibaba.nacos.naming.raft.Datum;
@ -315,7 +316,7 @@ public class DomainsManager {
try {
if (!dom.getEnableClientBeat()) {
getDom2LockMap().get(domName).lock();
getDom2LockMap().get(UtilsAndCommons.assembleFullServiceName(namespaceId, domName)).lock();
}
Datum datum1 = RaftCore.getDatum(UtilsAndCommons.getIPListStoreKey(dom));
@ -389,7 +390,7 @@ public class DomainsManager {
RaftCore.onPublish(datum, peer, increaseTerm);
} finally {
if (!dom.getEnableClientBeat()) {
getDom2LockMap().get(domName).unlock();
getDom2LockMap().get(UtilsAndCommons.assembleFullServiceName(namespaceId, domName)).unlock();
}
}
@ -510,6 +511,10 @@ public class DomainsManager {
public String namespaceId;
public Map<String, String> domName2Checksum = new HashMap<String, String>();
public DomainChecksum() {
this.namespaceId = Constants.REQUEST_PARAM_DEFAULT_NAMESPACE_ID;
}
public DomainChecksum(String namespaceId) {
this.namespaceId = namespaceId;
}

View File

@ -289,7 +289,10 @@ public class ApiCommands {
if (StringUtils.isBlank(clientBeat.getCluster())) {
clientBeat.setCluster(UtilsAndCommons.DEFAULT_CLUSTER_NAME);
}
String dom = WebUtils.required(request, "serviceName");
String dom = WebUtils.optional(request, "serviceName", StringUtils.EMPTY);
if (StringUtils.isBlank(dom)) {
dom = WebUtils.required(request, "dom");
}
String app;
app = WebUtils.optional(request, "app", StringUtils.EMPTY);
String clusterName = clientBeat.getCluster();
@ -1090,6 +1093,11 @@ public class ApiCommands {
onAddIP4Dom(requestWrapper);
proxyParams.put("clientIP", NetUtils.localServer());
proxyParams.put("notify", "true");
proxyParams.put("term", String.valueOf(RaftCore.getPeerSet().local().term));
proxyParams.put("timestamp", String.valueOf(timestamp));
if (domain.getEnableHealthCheck() && !domain.getEnableClientBeat()) {
syncOnAddIP4Dom(namespaceId, dom, proxyParams);
} else {
@ -1385,6 +1393,11 @@ public class ApiCommands {
onRemvIP4Dom(requestWrapper);
proxyParams.put("clientIP", NetUtils.localServer());
proxyParams.put("notify", "true");
proxyParams.put("term", String.valueOf(RaftCore.getPeerSet().local().term));
proxyParams.put("timestamp", String.valueOf(timestamp));
if (domain.getEnableHealthCheck() && !domain.getEnableClientBeat()) {
syncOnRemvIP4Dom(namespaceId, dom, proxyParams);
} else {
@ -1887,11 +1900,40 @@ public class ApiCommands {
public JSONObject allDomNames(HttpServletRequest request) throws Exception {
boolean responsibleOnly = Boolean.parseBoolean(WebUtils.optional(request, "responsibleOnly", "false"));
Map<String, Set<String>> domMap = domainsManager.getAllDomNames();
JSONObject result = new JSONObject();
// For old DNS-F client:
String dnsfVersion = "1.0.1";
String agent = request.getHeader("Client-Version");
ClientInfo clientInfo = new ClientInfo(agent);
if (clientInfo.type == ClientInfo.ClientType.DNS && clientInfo.version.compareTo(VersionUtil.parseVersion(dnsfVersion)) <= 0) {
List<String> doms = new ArrayList<String>();
Set<String> domSet = null;
if (domMap.containsKey(Constants.REQUEST_PARAM_DEFAULT_NAMESPACE_ID)) {
domSet = domMap.get(Constants.REQUEST_PARAM_DEFAULT_NAMESPACE_ID);
}
if (CollectionUtils.isEmpty(domSet)) {
result.put("doms", new HashSet<>());
result.put("count", 0);
return result;
}
for (String dom : domSet) {
if (DistroMapper.responsible(dom) || !responsibleOnly) {
doms.add(dom);
}
}
result.put("doms", doms);
result.put("count", doms.size());
return result;
}
Map<String, Set<String>> doms = new HashMap<>(16);
Map<String, Set<String>> domMap = domainsManager.getAllDomNames();
int count = 0;
for (String namespaceId : domMap.keySet()) {
doms.put(namespaceId, new HashSet<>());
for (String dom : domMap.get(namespaceId)) {
@ -1899,12 +1941,11 @@ public class ApiCommands {
doms.get(namespaceId).add(dom);
}
}
count += doms.get(namespaceId).size();
}
JSONObject result = new JSONObject();
result.put("doms", doms);
result.put("count", doms.size());
result.put("count", count);
return result;
}

View File

@ -21,7 +21,7 @@
<inceptionYear>2018</inceptionYear>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>0.8.0-SNAPSHOT</version>
<version>0.8.0</version>
<packaging>pom</packaging>
<name>Alibaba NACOS ${project.version}</name>

View File

@ -17,7 +17,7 @@
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<version>0.8.0-SNAPSHOT</version>
<version>0.8.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -170,6 +170,6 @@ CREATE TABLE roles (
role varchar(50) NOT NULL
);
INSERT INTO users (username, password, enabled) VALUES ('admin', '$2a$10$HxtJtd59imujvbux.i55zOGewhnJiLVXX8D9AETDMV.XtBLDGOXtW', TRUE);
INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);
INSERT INTO roles (username, role) VALUES ('admin', 'ROLE_ADMIN');
INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');