Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync remote resources in groups edit #104

Merged
merged 79 commits into from
Oct 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
8408d61
add remote resources from the groups view
davidcaron Sep 7, 2018
eb889b5
default service_url bug
davidcaron Sep 7, 2018
446ca7e
groups view: add flag + button to remove a resource not on remote server
davidcaron Sep 7, 2018
6106f24
add warning when there was an error fetching the data from remote server
davidcaron Sep 7, 2018
487de88
Clarify how to implement a new service by using an abstract class
davidcaron Sep 10, 2018
47149b0
Implement Geoserver
davidcaron Sep 10, 2018
890f521
allow integers for resource_names
davidcaron Sep 10, 2018
71c4649
Save remote resources in a separate table.
davidcaron Sep 12, 2018
3b8e1b8
Permission checkboxes post a 'permission' value
davidcaron Sep 12, 2018
4b1df51
Fix post request to edit permissions
davidcaron Sep 13, 2018
11755f5
Display resources sorted alphabetically
davidcaron Sep 13, 2018
e4cdb3e
Cleanup and document
davidcaron Sep 13, 2018
aeea8aa
Display resources sorted in edit service view
davidcaron Sep 13, 2018
fb2c6c2
ui color change
davidcaron Sep 13, 2018
d9b58c7
last sync info and clean all button
davidcaron Sep 13, 2018
49ddb13
also write resource type to database
davidcaron Sep 13, 2018
dad9f72
rename
davidcaron Sep 13, 2018
bd08cae
add resource_type attribute to resources
davidcaron Sep 13, 2018
0b076b1
reformat
davidcaron Sep 13, 2018
23f03d1
basic housekeeping function
davidcaron Sep 13, 2018
a7de1da
use service type instead of service name
davidcaron Sep 13, 2018
20bda2c
show message if sync is not implemented
davidcaron Sep 13, 2018
52a82b7
implement project-api
davidcaron Sep 13, 2018
94889cd
refactoring
davidcaron Sep 14, 2018
3e49695
services are uniquely identified using both their type and resource_name
davidcaron Sep 14, 2018
23c52ba
fix adding a nested resource
davidcaron Sep 14, 2018
f014586
don't add remote_path if it doesn't match remote resource
davidcaron Sep 14, 2018
11c7c16
fix 'Clean' button for a single resource
davidcaron Sep 14, 2018
e239217
fix housekeeping algorithm
davidcaron Sep 14, 2018
00eed72
add logging
davidcaron Sep 14, 2018
5f87d28
cron service to fetch remote resources
davidcaron Sep 17, 2018
05cd07f
Merge branch 'master' into sync-remote-resources-in-groups-edit
davidcaron Sep 17, 2018
c386a32
add note about accessing the database from the UI
davidcaron Sep 17, 2018
162fd2c
Merge remote-tracking branch 'origin/sync-remote-resources-in-groups-…
davidcaron Sep 17, 2018
614bfb4
edit user view: show remote and local resources
davidcaron Sep 17, 2018
0002a9c
edit user view: clean single resource
davidcaron Sep 17, 2018
b9c367b
edit user view: add a resource that is stored in the remote table
davidcaron Sep 17, 2018
4e46a2d
edit user view: display sync information and add 'Sync now' button
davidcaron Sep 17, 2018
caa9f9f
edit user view: add 'Clean all' button
davidcaron Sep 17, 2018
0701285
start cron from makefile
davidcaron Sep 18, 2018
0877e75
mark todos
davidcaron Sep 18, 2018
a5c8033
actually inherit abstract base class _SyncServiceInterface
davidcaron Sep 18, 2018
0f48f02
remove housekeeping script
davidcaron Sep 18, 2018
61ed291
handle single service failure in cron script
davidcaron Sep 18, 2018
f377717
refactoring
davidcaron Sep 18, 2018
3dfad47
ensure there was a successful synchronization done before offering to…
davidcaron Sep 18, 2018
e3e5258
don't modify directly the array given as argument
davidcaron Sep 18, 2018
f5fe862
display error message if resources are 'out of sync'
davidcaron Sep 18, 2018
b64f7a6
fix get_ids_to_clean
davidcaron Sep 18, 2018
5b22b29
identify resource by last id term instead of by name
davidcaron Sep 21, 2018
de84197
setup cron to use docker and docker-compose environment variables
davidcaron Sep 21, 2018
5570b5a
load env files before running cron job
davidcaron Sep 21, 2018
2936d34
don't flag a resource as absent from remote server if it's deeper...
davidcaron Sep 21, 2018
02d37d3
add max_depth property and simplify interface
davidcaron Sep 21, 2018
344ace6
Only push remote resource id to UI.
davidcaron Sep 24, 2018
bd30ee1
ignore generated docs + single service api
fmigneault Sep 27, 2018
e32719a
alembic upgrade db service types
fmigneault Sep 27, 2018
ef7d596
fix empty strings in mako templates
davidcaron Sep 28, 2018
be920d4
iteritems -> items
davidcaron Sep 28, 2018
92fd215
adjust api providers
fmigneault Sep 28, 2018
f52ffb0
identify a service by its id instead of its name and type
davidcaron Sep 28, 2018
3f71d52
get services sooner so that the cur_svc_type is not "default"
davidcaron Sep 28, 2018
ea05900
ui syntax
davidcaron Sep 28, 2018
73580a9
related to #107, prepare for new table column
davidcaron Sep 28, 2018
4c79982
Merge branch 'master' of https://github.com/ouranosinc/magpie into sy…
davidcaron Sep 28, 2018
6e799e1
update 'api' in db + add sync_type
fmigneault Sep 28, 2018
1f68d5a
remove init that messes up import alembic in magpie
fmigneault Sep 28, 2018
1b2ae70
Merge remote-tracking branch 'origin/service-api-ponctual-permissions…
davidcaron Oct 1, 2018
70117d6
fix migrations
davidcaron Oct 1, 2018
0a07acd
[api change] add service_sync_type to services
davidcaron Oct 1, 2018
19ff48f
edit user and edit group views handle multiple services of same type
davidcaron Oct 1, 2018
f881f44
fix register_services function to be nice with migrations and ...
davidcaron Oct 1, 2018
f60344a
Revert: these files shouldn't have been commited
davidcaron Oct 1, 2018
7e5bc28
add sync_type to providers
davidcaron Oct 1, 2018
8023f4c
don't crash when sync_type is absent from providers.cfg
davidcaron Oct 1, 2018
f93d97a
fix update sync_type when force updating providers
davidcaron Oct 2, 2018
06ba6b0
let sync_type be None when passed to json renderer
davidcaron Oct 2, 2018
33d576b
fix migrations
davidcaron Oct 2, 2018
3bcfa22
fix error message issue
davidcaron Oct 2, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ MAINTAINER Francis Charette-Migneault
RUN apt-get update && apt-get install -y \
build-essential \
supervisor \
cron \
curl \
libssl-dev \
libffi-dev \
Expand All @@ -23,4 +24,11 @@ COPY ./ $MAGPIE_DIR
RUN make install -f $MAGPIE_DIR/Makefile
RUN make docs -f $MAGPIE_DIR/Makefile

CMD ["make", "start"]
# magpie cron service
ADD magpie-cron /etc/cron.d/magpie-cron
RUN chmod 0644 /etc/cron.d/magpie-cron
RUN touch ~/magpie_cron_status.log
# set /etc/environment so that cron runs using the environment variables set by docker
RUN env >> /etc/environment

CMD make start
7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,12 @@ install: sysinstall
@echo "Installing Magpie..."
python setup.py install

.PHONY: cron
cron:
@echo "Starting Cron service..."
cron

.PHONY: start
start: install
start: cron install
@echo "Starting Magpie..."
exec gunicorn -b 0.0.0.0:2001 --paste "$(CUR_DIR)/magpie/magpie.ini" --workers 10 --preload
2 changes: 2 additions & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
magpie*.rst
modules.rst
1 change: 1 addition & 0 deletions env/magpie.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ MAGPIE_ADMIN_USER=admin
MAGPIE_ADMIN_PASSWORD=qwerty
MAGPIE_ANONYMOUS_USER=anonymous
MAGPIE_USERS_GROUP=users
MAGPIE_CRON_LOG=~/magpie_cron.log
PHOENIX_USER=phoenix
PHOENIX_PASSWORD=qwerty
PHOENIX_PORT=8443
Expand Down
1 change: 1 addition & 0 deletions magpie-cron
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0 * * * * root /bin/bash -c "set -a ; . $MAGPIE_DIR/env/magpie.env ; . $MAGPIE_DIR/magpie/env/magpie.env ; . $MAGPIE_DIR/env/postgres.env ; . $MAGPIE_DIR/magpie/env/postgres.env ; set +a ; python -c 'from magpie.helpers.sync_resources import main; main()'" > ~/magpie_cron_status.log 2>&1
9 changes: 9 additions & 0 deletions magpie/alembic/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from magpie.definitions.sqlalchemy_definitions import *


def has_column(context, table_name, column_name):
inspector = reflection.Inspector.from_engine(context.connection.engine)
for column in inspector.get_columns(table_name=table_name):
if column_name in column['name']:
return True
return False
85 changes: 85 additions & 0 deletions magpie/alembic/versions/73639c63c4fc_unified_api_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
"""unified api service

Revision ID: 73639c63c4fc
Revises: d01af1f2e445
Create Date: 2018-09-27 16:12:02.282830

"""
import os, sys

cur_file = os.path.abspath(__file__)
root_dir = os.path.dirname(cur_file) # version
root_dir = os.path.dirname(root_dir) # alembic
root_dir = os.path.dirname(root_dir) # magpie
root_dir = os.path.dirname(root_dir) # root
sys.path.insert(0, root_dir)

from alembic import op
from alembic.context import get_context
from magpie.definitions.sqlalchemy_definitions import *
# from magpie.models import Service
from sqlalchemy.sql import table
from sqlalchemy import func

Session = sessionmaker()

# revision identifiers, used by Alembic.
revision = '73639c63c4fc'
down_revision = 'd01af1f2e445'
branch_labels = None
depends_on = None


def upgrade():
context = get_context()
if isinstance(context.connection.engine.dialect, PGDialect):
# add 'sync_type' column if missing
op.add_column('services', sa.Column('sync_type', sa.UnicodeText(), nullable=True))

services = table('services',
sa.Column('url', sa.UnicodeText()),
sa.Column('type', sa.UnicodeText()),
sa.Column('sync_type', sa.UnicodeText()),
)

# transfer 'api' service types
op.execute(services.
update().
where(services.c.type == op.inline_literal('project-api')).
values({'type': op.inline_literal('api'),
'url': services.c.url + "/api",
'sync_type': op.inline_literal('project-api')
})
)
op.execute(services.
update().
where(services.c.type == op.inline_literal('geoserver-api')).
values({'type': op.inline_literal('api'),
'sync_type': op.inline_literal('geoserver-api')
})
)


def downgrade():
service = table('services',
sa.Column('url', sa.UnicodeText()),
sa.Column('type', sa.UnicodeText()),
sa.Column('sync_type', sa.UnicodeText()),
)

# transfer 'api' service types
op.execute(service.
update().
where(service.c.sync_type == op.inline_literal('project-api')).
values({'type': op.inline_literal('project-api'),
'url': func.replace(service.c.url, '/api', ''),
})
)
op.execute(service.
update().
where(service.c.sync_type == op.inline_literal('geoserver-api')).
values({'type': op.inline_literal('geoserver-api'),
})
)

op.drop_column('services', 'sync_type')
16 changes: 4 additions & 12 deletions magpie/alembic/versions/a395ef9d3fe6_reference_root_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,7 @@ def upgrade():
context.connection.engine.dialect.supports_sane_multi_rowcount = False

if isinstance(context.connection.engine.dialect, PGDialect):

# check if column exists, add it otherwise
inspector = reflection.Inspector.from_engine(context.connection.engine)
has_root_service_column = False
for column in inspector.get_columns(table_name='resources'):
if 'root_service_id' in column['name']:
has_root_service_column = True
break

if not has_root_service_column:
op.add_column('resources', sa.Column('root_service_id', sa.Integer(), nullable=True))
op.add_column('resources', sa.Column('root_service_id', sa.Integer(), nullable=True))

# add existing resource references to their root service, loop through reference tree chain
all_resources = session.query(models.Resource)
Expand All @@ -61,4 +51,6 @@ def upgrade():


def downgrade():
pass
context = get_context()
if isinstance(context.connection.engine.dialect, PGDialect):
op.drop_column('resources', 'root_service_id')
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def change_project_api_resource_type(new_type_name):
if isinstance(context.connection.engine.dialect, PGDialect):
# obtain service 'project-api'
session = Session(bind=op.get_bind())
project_api_svc = models.Service.by_service_name('project-api', db_session=session)
project_api_svc = session.query(models.Service.resource_id).filter_by(resource_name='project-api').first()

# nothing to edit if it doesn't exist, otherwise change resource types to 'route'
if project_api_svc:
Expand Down
64 changes: 64 additions & 0 deletions magpie/alembic/versions/d01af1f2e445_create_remote_sync_tables.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"""create remote sync tables

Revision ID: d01af1f2e445
Revises: c352a98d570e
Create Date: 2018-09-11 10:56:23.779143

"""
import os, sys

cur_file = os.path.abspath(__file__)
root_dir = os.path.dirname(cur_file) # version
root_dir = os.path.dirname(root_dir) # alembic
root_dir = os.path.dirname(root_dir) # magpie
root_dir = os.path.dirname(root_dir) # root
sys.path.insert(0, root_dir)

from alembic import op
from magpie.definitions.sqlalchemy_definitions import *

Session = sessionmaker()

import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = 'd01af1f2e445'
down_revision = 'c352a98d570e'
branch_labels = None
depends_on = None


def upgrade():
op.create_table('remote_resources',
sa.Column('resource_id', sa.Integer(), primary_key=True,
nullable=False, autoincrement=True),
sa.Column('service_id',
sa.Integer(),
sa.ForeignKey('services.resource_id', onupdate='CASCADE', ondelete='CASCADE'),
index=True,
nullable=False),
sa.Column('parent_id',
sa.Integer(),
sa.ForeignKey('remote_resources.resource_id', onupdate='CASCADE', ondelete='SET NULL'),
nullable=True),
sa.Column('ordering', sa.Integer(), default=0, nullable=False),
sa.Column('resource_name', sa.Unicode(100), nullable=False),
sa.Column('resource_type', sa.Unicode(30), nullable=False),
)
op.create_table('remote_resources_sync_info',
sa.Column('id', sa.Integer(), primary_key=True, nullable=False, autoincrement=True),
sa.Column('service_id',
sa.Integer(),
sa.ForeignKey('services.resource_id', onupdate='CASCADE', ondelete='CASCADE'),
index=True,
nullable=False),
sa.Column('remote_resource_id',
sa.Integer(),
sa.ForeignKey('remote_resources.resource_id', onupdate='CASCADE', ondelete='CASCADE')),
sa.Column('last_sync', sa.DateTime(), nullable=True),
)


def downgrade():
op.drop_table('remote_resources_sync_info')
op.drop_table('remote_resources')
10 changes: 10 additions & 0 deletions magpie/api/api_rest_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,11 @@ class ServiceBodySchema(colander.MappingSchema):
description="Type of the service",
example="thredds"
)
service_sync_type = colander.SchemaNode(
colander.String(),
description="Type of resource synchronization implementation.",
example="thredds"
)
public_url = colander.SchemaNode(
colander.String(),
description="Proxy URL available for public access with permissions",
Expand Down Expand Up @@ -857,6 +862,11 @@ class Services_POST_BodySchema(colander.MappingSchema):
description="Type of the service to create",
example="wps"
)
service_sync_type = colander.SchemaNode(
colander.String(),
description="Type of the service to create",
example="wps"
)
service_url = colander.SchemaNode(
colander.String(),
description="Private URL of the service to create",
Expand Down
1 change: 1 addition & 0 deletions magpie/api/management/service/service_formats.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ def fmt_svc(svc, perms):
u'service_url': str(svc.url),
u'service_name': str(svc.resource_name),
u'service_type': str(svc.type),
u'service_sync_type': svc.sync_type,
u'resource_id': svc.resource_id,
u'permission_names': sorted(service_type_dict[svc.type].permission_names if perms is None else perms)
}
Expand Down
1 change: 1 addition & 0 deletions magpie/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
MAGPIE_ANONYMOUS_EMAIL = '{}@mail.com'.format(MAGPIE_ANONYMOUS_USER)
MAGPIE_ANONYMOUS_GROUP = MAGPIE_ANONYMOUS_USER
MAGPIE_USERS_GROUP = os.getenv('MAGPIE_USERS_GROUP', 'users')
MAGPIE_CRON_LOG = os.getenv('MAGPIE_CRON_LOG', '~/magpie-cron.log')
PHOENIX_USER = os.getenv('PHOENIX_USER', 'phoenix')
PHOENIX_PASSWORD = os.getenv('PHOENIX_PASSWORD', 'qwerty')
PHOENIX_PORT = int(os.getenv('PHOENIX_PORT', 8443))
Expand Down
2 changes: 1 addition & 1 deletion magpie/definitions/ziggurat_definitions.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# import required definitions
from ziggurat_foundations import ziggurat_model_init
from ziggurat_foundations.models import groupfinder
from ziggurat_foundations.models.base import get_db_session
from ziggurat_foundations.models.base import get_db_session, BaseModel
from ziggurat_foundations.models.external_identity import ExternalIdentityMixin
from ziggurat_foundations.models.group import GroupMixin
from ziggurat_foundations.models.group_permission import GroupPermissionMixin
Expand Down
Loading