diff --git a/.env.example b/.env.example
index b8794c10..529d3ce9 100644
--- a/.env.example
+++ b/.env.example
@@ -1,3 +1,5 @@
+RUNSERVER_PORT=8080
+
SLACK_CLIENT_OAUTH_ID=
SLACK_CLIENT_OAUTH_SECRET=
SLACK_API_TOKEN=
@@ -19,13 +21,13 @@ SENDGRID_FROM_EMAIL=
DJANGO_SETTINGS_MODULE=settings.dev
SECRET_KEY=jkashdkjashdkjh
-BASE_URL=http://localhost:8000
+BASE_URL=http://localhost:8080
FEATURE_TELEGRAM_INTEGRATION_ENABLED=True
FEATURE_SLACK_INTEGRATION_ENABLED=True
FEATURE_EXTRA_MESSAGING_BACKENDS_ENABLED=
-SLACK_INSTALL_RETURN_REDIRECT_HOST=http://localhost:8000
+SLACK_INSTALL_RETURN_REDIRECT_HOST=http://localhost:8080
SOCIAL_AUTH_REDIRECT_IS_HTTPS=False
GRAFANA_INCIDENT_STATIC_API_KEY=
diff --git a/DEVELOPER.md b/DEVELOPER.md
index 8af642f3..37a0a526 100644
--- a/DEVELOPER.md
+++ b/DEVELOPER.md
@@ -64,7 +64,7 @@ python manage.py createsuperuser
3. Launch the backend:
```bash
# Http server:
-python manage.py runserver
+python manage.py runserver 8080
# Worker for background tasks (run it in the parallel terminal, don't forget to export .env there)
python manage.py start_celery
@@ -73,7 +73,7 @@ python manage.py start_celery
celery -A engine beat -l info
```
-4. All set! Check out internal API endpoints at http://localhost:8000/.
+4. All set! Check out internal API endpoints at http://localhost:8080/.
### Frontend setup
@@ -102,7 +102,7 @@ python manage.py issue_invite_for_the_frontend --override
6. Some configuration fields will appear be available. Fill them out and click Initialize OnCall
```
OnCall API URL:
-http://host.docker.internal:8000
+http://host.docker.internal:8080
Invitation Token (Single use token to connect Grafana instance):
Response from the invite generator command (check above)
@@ -226,6 +226,7 @@ pytest --ds=settings.dev
- Set Settings to settings/dev.py
5. Create a new Django Server run configuration to Run/Debug the engine
- Use a plugin such as EnvFile to load the .env file
+ - Change port from 8000 to 8080
## Update drone build
The .drone.yml build file must be signed when changes are made to it. Follow these steps:
diff --git a/README.md b/README.md
index 6e94081a..b9569831 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-Developer-friendly, incident response with brilliant Slack integration.
+Developer-friendly incident response with brilliant Slack integration.
@@ -20,7 +20,7 @@ curl https://github.com/grafana/oncall/blob/dev/docker-compose.yml -o docker-com
2. Set variables:
```bash
-echo "DOMAIN=http://localhost
+echo "DOMAIN=http://localhost:8080
SECRET_KEY=my_random_secret_must_be_more_than_32_characters_long
RABBITMQ_PASSWORD=rabbitmq_secret_pw
MYSQL_PASSWORD=mysql_secret_pw
diff --git a/docker-compose-developer.yml b/docker-compose-developer.yml
index 622eddd4..e35c3c70 100644
--- a/docker-compose-developer.yml
+++ b/docker-compose-developer.yml
@@ -7,7 +7,7 @@ services:
platform: linux/x86_64
mem_limit: 500m
cpus: 0.5
- command: --default-authentication-plugin=mysql_native_password
+ command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
restart: always
ports:
- 3306:3306
diff --git a/docker-compose.yml b/docker-compose.yml
index 457fd6b5..c4695fd8 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -92,13 +92,15 @@ services:
depends_on:
mysql:
condition: service_healthy
+ rabbitmq:
+ condition: service_started
mysql:
image: mysql:5.7
platform: linux/x86_64
mem_limit: 500m
cpus: 0.5
- command: --default-authentication-plugin=mysql_native_password
+ command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
restart: always
ports:
- 3306:3306
diff --git a/docs/img/GrafanaOnCall_Stack_Fullcolor_black.png b/docs/img/GrafanaOnCall_Stack_Fullcolor_black.png
new file mode 100644
index 00000000..94d3c86b
Binary files /dev/null and b/docs/img/GrafanaOnCall_Stack_Fullcolor_black.png differ
diff --git a/docs/img/How Grafana OnCall works_diagram.png b/docs/img/How Grafana OnCall works_diagram.png
new file mode 100644
index 00000000..6812230f
Binary files /dev/null and b/docs/img/How Grafana OnCall works_diagram.png differ
diff --git a/docs/sources/oncall-api-reference/_index.md b/docs/sources/oncall-api-reference/_index.md
index b696b0fc..000ee452 100644
--- a/docs/sources/oncall-api-reference/_index.md
+++ b/docs/sources/oncall-api-reference/_index.md
@@ -21,15 +21,12 @@ To authorize, use the **Authorization** header:
```shell
# With shell, you can just pass the correct header with each request
-curl "api_endpoint_here" --header "Authorization: meowmeowmeow"
+curl "api_endpoint_here" --header "Authorization: "api_key_here""
```
-Note that `meowmeowmeow` is a valid key for test purposes.
-Replace `meowmeowmeow` with your API key in production.
+Grafana OnCall uses API keys to allow access to the API. You can request a new OnCall API key in OnCall -> Settings page.
-Grafana OnCall uses API keys to allow access to the API. You can request a new OnCall API key in the API section.
-
-An API key is specific to a user and a Grafana stack. If you want to switch to a different team configuration, request a different API key.
+An API key is specific to a user and a Grafana stack. If you want to switch to a different stack configuration, request a different API key.
## Pagination
diff --git a/docs/sources/open-source.md b/docs/sources/open-source.md
index 8d77b0d0..fc31bf69 100644
--- a/docs/sources/open-source.md
+++ b/docs/sources/open-source.md
@@ -17,7 +17,7 @@ We prepared three environments for OSS users:
## Production Environment
-TBD
+We prepared the helm chart for production environment: https://github.com/grafana/oncall/helm
## Slack Setup
@@ -32,7 +32,7 @@ Grafana OnCall Slack integration use a lot of Slack API features:
# Choose the unique prefix instead of pretty-turkey-83
# Localtunnel will generate an url, e.g. https://pretty-turkey-83.loca.lt
# it is referred as below
-lt --port 8000 -s pretty-turkey-83 --print-requests
+lt --port 8080 -s pretty-turkey-83 --print-requests
```
3. If you use localtunnel, open your external URL and click "Continue" to allow requests to bypass the warning page.
diff --git a/engine/apps/base/models/live_setting.py b/engine/apps/base/models/live_setting.py
index 59126f3d..54a5299d 100644
--- a/engine/apps/base/models/live_setting.py
+++ b/engine/apps/base/models/live_setting.py
@@ -114,8 +114,8 @@ class LiveSetting(models.Model):
),
"SEND_ANONYMOUS_USAGE_STATS": (
"Grafana OnCall will send anonymous, but uniquely-identifiable usage analytics to Grafana Labs."
- " These statistics are sent to https://stats.grafana.org/. For more information on what's sent, look at"
- " https://github.com/grafana/oncall/blob/dev/engine/apps/oss_installation/usage_stats.py#L29"
+ " These statistics are sent to https://stats.grafana.org/. For more information on what's sent, look at the "
+ " source code."
),
"GRAFANA_CLOUD_ONCALL_TOKEN": "Secret token for Grafana Cloud OnCall instance.",
"GRAFANA_CLOUD_ONCALL_HEARTBEAT_ENABLED": "Enable hearbeat integration with Grafana Cloud OnCall.",
diff --git a/engine/settings/base.py b/engine/settings/base.py
index 16d605ac..baba3861 100644
--- a/engine/settings/base.py
+++ b/engine/settings/base.py
@@ -226,9 +226,7 @@ USE_TZ = True
# https://docs.djangoproject.com/en/2.1/howto/static-files/
STATIC_URL = "/static/"
-STATICFILES_DIRS = [
- "./static",
-]
+STATIC_ROOT = "./static/"
CELERY_BROKER_URL = "amqp://rabbitmq:rabbitmq@localhost:5672"
diff --git a/engine/uwsgi.ini b/engine/uwsgi.ini
index 17a92d60..6f612248 100644
--- a/engine/uwsgi.ini
+++ b/engine/uwsgi.ini
@@ -18,4 +18,4 @@ post-buffering=1
logger=stdio
log-format=source=engine:uwsgi status=%(status) method=%(method) path=%(uri) latency=%(secs) google_trace_id=%(var.HTTP_X_CLOUD_TRACE_CONTEXT) protocol=%(proto) resp_size=%(size) req_body_size=%(cl)
-log-encoder=format ${strftime:%%Y-%%m-%%d %%H:%%M:%%S} ${msgnl}
\ No newline at end of file
+log-encoder=format ${strftime:%%Y-%%m-%%d %%H:%%M:%%S} ${msgnl}
diff --git a/grafana-plugin/CHANGELOG.md b/grafana-plugin/CHANGELOG.md
deleted file mode 120000
index 04c99a55..00000000
--- a/grafana-plugin/CHANGELOG.md
+++ /dev/null
@@ -1 +0,0 @@
-../CHANGELOG.md
\ No newline at end of file
diff --git a/grafana-plugin/CHANGELOG.md b/grafana-plugin/CHANGELOG.md
new file mode 100644
index 00000000..8893332c
--- /dev/null
+++ b/grafana-plugin/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Change Log
+
+## 0.0.71 (2022-06-06)
+
+- Initial Release
\ No newline at end of file
diff --git a/grafana-plugin/src/containers/DefaultPageLayout/DefaultPageLayout.tsx b/grafana-plugin/src/containers/DefaultPageLayout/DefaultPageLayout.tsx
index 7d446ef1..7b2c23a6 100644
--- a/grafana-plugin/src/containers/DefaultPageLayout/DefaultPageLayout.tsx
+++ b/grafana-plugin/src/containers/DefaultPageLayout/DefaultPageLayout.tsx
@@ -100,7 +100,9 @@ const DefaultPageLayout: FC = observer((props) => {
currentTeam &&
currentUser &&
store.isUserActionAllowed(UserAction.UpdateOwnSettings) &&
- (!currentUser.verified_phone_number || !currentUser.slack_user_identity) &&
+ (!currentUser.verified_phone_number ||
+ !currentUser.slack_user_identity ||
+ currentUser.cloud_connection_status !== 3) &&
!getItem(AlertID.CONNECTIVITY_WARNING)
) && (
= observer((props) => {
{'. '}
>
)}
- {!currentUser.verified_phone_number && 'Your phone number is not verified. '}
+ {currentUser.cloud_connection_status !== 3 &&
+ !currentUser.verified_phone_number &&
+ 'Your phone number is not verified. '}
{currentTeam.slack_team_identity &&
!currentUser.slack_user_identity &&
'Your slack account is not connected. '}
diff --git a/grafana-plugin/src/containers/PluginConfigPage/PluginConfigPage.tsx b/grafana-plugin/src/containers/PluginConfigPage/PluginConfigPage.tsx
index 5ca6d87d..d3996c51 100644
--- a/grafana-plugin/src/containers/PluginConfigPage/PluginConfigPage.tsx
+++ b/grafana-plugin/src/containers/PluginConfigPage/PluginConfigPage.tsx
@@ -35,11 +35,10 @@ const cx = cn.bind(styles);
interface Props extends PluginConfigPageProps> {}
export const PluginConfigPage = (props: Props) => {
- const grafanaUrlDefault = getItem('grafanaUrl') || window.location.origin;
const { plugin } = props;
const [onCallApiUrl, setOnCallApiUrl] = useState(getItem('onCallApiUrl'));
const [onCallInvitationToken, setOnCallInvitationToken] = useState();
- const [grafanaUrl, setGrafanaUrl] = useState(grafanaUrlDefault);
+ const [grafanaUrl, setGrafanaUrl] = useState(getItem('grafanaUrl'));
const [pluginConfigLoading, setPluginConfigLoading] = useState(true);
const [pluginStatusOk, setPluginStatusOk] = useState();
const [pluginStatusMessage, setPluginStatusMessage] = useState();
@@ -298,10 +297,10 @@ Seek for such a line: “Your invite token: <> , use it in the Graf
label="OnCall backend URL"
description={
- It should be rechable from Grafana. Possible options:
- http://host.docker.internal:8000 (if you run backend in the docker locally)
+ It should be reachable from Grafana. Possible options:
+ http://host.docker.internal:8080 (if you run backend in the docker locally)
- http://localhost:8000
+ http://localhost:8080
...
}
diff --git a/grafana-plugin/src/containers/UserSettings/parts/tabs/CloudPhoneSettings/CloudPhoneSettings.tsx b/grafana-plugin/src/containers/UserSettings/parts/tabs/CloudPhoneSettings/CloudPhoneSettings.tsx
index 724b4712..74438027 100644
--- a/grafana-plugin/src/containers/UserSettings/parts/tabs/CloudPhoneSettings/CloudPhoneSettings.tsx
+++ b/grafana-plugin/src/containers/UserSettings/parts/tabs/CloudPhoneSettings/CloudPhoneSettings.tsx
@@ -48,7 +48,7 @@ const CloudPhoneSettings = observer((props: CloudPhoneSettingsProps) => {
}, []);
const handleLinkClick = (link: string) => {
- window.location.replace(link);
+ window.open(link, '_blank');
};
const syncUser = async () => {
diff --git a/grafana-plugin/src/index.css b/grafana-plugin/src/index.css
index eeeff2de..bdfece87 100644
--- a/grafana-plugin/src/index.css
+++ b/grafana-plugin/src/index.css
@@ -30,12 +30,19 @@
background: var(--highlighted-row-bg);
}
+/* This is for Grafana 8, remove later */
@media (max-width: 1540px) {
.page-header__tabs > ul > li > a > div {
display: none;
}
}
+@media (max-width: 1540px) {
+ .page-header__tabs > div > div > a > div {
+ display: none;
+ }
+}
+
@media (max-width: 1300px) {
.sidemenu {
position: fixed !important;
diff --git a/grafana-plugin/src/pages/cloud/CloudPage.tsx b/grafana-plugin/src/pages/cloud/CloudPage.tsx
index d81ce0c9..63df35e0 100644
--- a/grafana-plugin/src/pages/cloud/CloudPage.tsx
+++ b/grafana-plugin/src/pages/cloud/CloudPage.tsx
@@ -69,10 +69,6 @@ const CloudPage = observer((props: CloudPageProps) => {
setApiKeyError(false);
}, []);
- const saveKeyAndConnect = () => {
- setShowConfirmationModal(true);
- };
-
const disconnectCloudOncall = () => {
setCloudIsConnected(false);
store.cloudStore.disconnectToCloud();
@@ -105,7 +101,7 @@ const CloudPage = observer((props: CloudPageProps) => {
};
const handleLinkClick = (link: string) => {
- window.location.replace(link);
+ window.open(link, '_blank');
};
const renderButtons = (user: Cloud) => {
@@ -130,10 +126,9 @@ const CloudPage = observer((props: CloudPageProps) => {
return (
@@ -343,7 +338,7 @@ const CloudPage = observer((props: CloudPageProps) => {
>
-