Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
G
g1-g2-ostack-cloud-migration
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
cloud
g1-g2-ostack-cloud-migration
Commits
bd1375e5
Commit
bd1375e5
authored
1 year ago
by
František Řezníček
Browse files
Options
Downloads
Patches
Plain Diff
feat: initial kick of the migration script and documentation
parent
01b58ae6
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
README.md
+26
-0
26 additions, 0 deletions
README.md
ci/project-migrator.py
+162
-0
162 additions, 0 deletions
ci/project-migrator.py
with
188 additions
and
0 deletions
README.md
+
26
−
0
View file @
bd1375e5
...
...
@@ -2,3 +2,29 @@
e-INFRA CZ G1 to G2 OpenStack cloud workload migration.
This is automation CI pipeline is core of the G1 to G2 migration process.
More details of the progress can be found
[
here
](
https://docs.e-infra.cz/compute/openstack/migration-to-g2-openstack-cloud/
)
.
## Migration checklist
*
[ ] Define date of the workload migration
*
[ ] Is the project personal or group?
*
[ ] Are there any data in object store?
*
[ ] Are there any DNS records on FIPs?
## How to launch G1 to G2 migration
Input argumenta are:
*
`PROJECT_NAME`
*
name of the project in G1 and in G2 OpenStack cloud
*
`KEYPAIR_ID`
*
id of any existing keypair in G1 or G2 cloud
*
`SERVER_NAME`
*
migrate just single VM instance with defined name
This diff is collapsed.
Click to expand it.
ci/project-migrator.py
0 → 100755
+
162
−
0
View file @
bd1375e5
#!/usr/bin/env python3
"""
OpenStack project multicloud migrator
"""
import
argparse
import
re
import
sys
import
paramiko
import
keystoneauth1.session
from
keystoneauth1.identity
import
v3
from
openstack
import
connection
from
keystoneauth1
import
session
def
get_openrc
(
file_handle
):
"""
parse and return OpenRC file
"""
openrc_vars
=
{}
for
line
in
file_handle
:
match
=
re
.
match
(
r
'
^export (\w+)=(.+)$
'
,
line
.
strip
())
if
match
:
openrc_vars
[
match
.
group
(
1
)]
=
match
.
group
(
2
).
strip
(
'"'
)
return
openrc_vars
def
get_ostack_session_connection
(
openrc_vars
):
"""
"""
auth_args
=
{
'
auth_url
'
:
openrc_vars
.
get
(
'
OS_AUTH_URL
'
),
'
username
'
:
openrc_vars
.
get
(
'
OS_USERNAME
'
),
'
password
'
:
openrc_vars
.
get
(
'
OS_PASSWORD
'
),
'
project_name
'
:
openrc_vars
.
get
(
'
OS_PROJECT_NAME
'
),
'
project_domain_name
'
:
openrc_vars
.
get
(
'
OS_PROJECT_DOMAIN_NAME
'
),
'
user_domain_name
'
:
openrc_vars
.
get
(
'
OS_USER_DOMAIN_NAME
'
),
'
project_domain_id
'
:
openrc_vars
.
get
(
'
OS_PROJECT_DOMAIN_ID
'
),
'
user_domain_id
'
:
openrc_vars
.
get
(
'
OS_USER_DOMAIN_ID
'
),
}
auth
=
v3
.
Password
(
**
auth_args
)
ostack_sess
=
session
.
Session
(
auth
=
auth
)
ostack_conn
=
connection
.
Connection
(
session
=
ostack_sess
)
return
ostack_sess
,
ostack_conn
def
get_ostack_project
(
ostack_connection
,
project_name
):
project
=
None
for
i_project
in
ostack_connection
.
list_projects
():
if
i_project
.
name
==
project_name
:
project
=
i_project
return
project
def
get_ostack_project_keypairs
(
ostack_connection
,
project_name
):
return
ostack_connection
.
compute
.
keypairs
()
def
get_ostack_project_security_groups
(
ostack_connection
,
project_name
):
return
ostack_connection
.
network
.
security_groups
()
def
get_ostack_project_servers
(
ostack_connection
,
project_name
):
return
ostack_connection
.
compute
.
servers
()
def
get_ostack_project_volumes
(
ostack_connection
,
project_name
):
return
ostack_connection
.
block_store
.
volumes
()
def
remote_cmd_exec
(
hostname
,
username
,
key_filename
,
command
):
# Create SSH client
ssh_client
=
paramiko
.
SSHClient
()
# Automatically add untrusted hosts
ssh_client
.
set_missing_host_key_policy
(
paramiko
.
AutoAddPolicy
())
try
:
# Connect to the remote host
pkey
=
paramiko
.
RSAKey
.
from_private_key_file
(
key_filename
)
ssh_client
.
connect
(
hostname
,
username
=
username
,
pkey
=
pkey
,
look_for_keys
=
False
)
# Execute the command
stdin
,
stdout
,
stderr
=
ssh_client
.
exec_command
(
command
)
# Read the output
output
=
stdout
.
read
().
decode
().
strip
()
# Close the SSH connection
ssh_client
.
close
()
return
output
except
Exception
as
e
:
print
(
"
Error:
"
,
e
)
return
None
def
main
(
args
):
"""
"""
# connect to source cloud
source_openrc
=
get_openrc
(
args
.
source_openrc
)
source_sess
,
source_conn
=
get_ostack_session_connection
(
source_openrc
)
# connect to destination cloud
destination_openrc
=
get_openrc
(
args
.
destination_openrc
)
destination_sess
,
destination_conn
=
get_ostack_session_connection
(
destination_openrc
)
# check project exists in source and destination
source_project
=
get_ostack_project
(
source_conn
,
args
.
project_name
)
destination_project
=
get_ostack_project
(
destination_conn
,
args
.
project_name
)
# connect to migrator node
reply
=
remote_cmd_exec
(
args
.
ceph_migrator_host
,
args
.
ceph_migrator_user
,
args
.
ceph_migrator_sshkeyfile
.
name
,
'
uname -a
'
)
# get source/destination keypairs
source_keypairs
=
get_ostack_project_keypairs
(
source_conn
,
args
.
project_name
)
destination_keypairs
=
get_ostack_project_keypairs
(
destination_conn
,
args
.
project_name
)
# get source/destination security groups
source_security_groups
=
get_ostack_project_security_groups
(
source_conn
,
args
.
project_name
)
destination_security_groups
=
get_ostack_project_security_groups
(
destination_conn
,
args
.
project_name
)
# get source/destination servers in the project
source_project_servers
=
get_ostack_project_servers
(
source_conn
,
args
.
project_name
)
destination_project_servers
=
get_ostack_project_servers
(
destination_conn
,
args
.
project_name
)
# get source/destination volumes in the project
source_project_volumes
=
get_ostack_project_volumes
(
source_conn
,
args
.
project_name
)
destination_project_volumes
=
get_ostack_project_volumes
(
destination_conn
,
args
.
project_name
)
#print(dir(source_conn))
print
(
locals
())
# connect to source cloud
# connect to ceph migrator node
pass
# main() call (argument parsing)
# ---------------------------------------------------------------------------
if
__name__
==
"
__main__
"
:
AP
=
argparse
.
ArgumentParser
(
epilog
=
globals
().
get
(
'
__doc__
'
),
formatter_class
=
argparse
.
RawDescriptionHelpFormatter
)
AP
.
add_argument
(
'
--source-openrc
'
,
default
=
None
,
type
=
argparse
.
FileType
(
'
r
'
),
required
=
True
,
help
=
'
Source cloud authentication (OpenRC file)
'
)
AP
.
add_argument
(
'
--destination-openrc
'
,
default
=
None
,
type
=
argparse
.
FileType
(
'
r
'
),
required
=
True
,
help
=
'
Destination cloud authentication (OpenRC file)
'
)
AP
.
add_argument
(
'
--ceph-migrator-host
'
,
default
=
'
controller-ostack.stage.cloud.muni.cz
'
,
help
=
'
OpenStack migrator ceph node host
'
)
AP
.
add_argument
(
'
--ceph-migrator-user
'
,
default
=
'
root
'
,
help
=
'
OpenStack migrator ceph node username
'
)
AP
.
add_argument
(
'
--ceph-migrator-sshkeyfile
'
,
default
=
None
,
type
=
argparse
.
FileType
(
'
r
'
),
help
=
'
OpenStack migrator SSH keyfile
'
)
AP
.
add_argument
(
'
--project-name
'
,
default
=
None
,
required
=
True
,
help
=
'
OpenStack project name (identical in both clouds)
'
)
AP
.
add_argument
(
'
--keypair-id
'
,
default
=
None
,
required
=
True
,
help
=
'
Any keypair ID within selected OpenStack project
'
)
#AP.add_argument('--hide-skipped-actions', default=False, action='store_true',
# help="Hide skipped ansible actions")
sys
.
exit
(
main
(
AP
.
parse_args
()))
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment