Başlangıç

Başlangıç

Bu kılavuzu okuması gerekenler

Bu kılavuz OpenStack bulutlarında uygulama kurmak isteyen deneyimli yazılım geliştiricileri içindir.

OpenStack’e aşina iseniz ama bir bulut uygulaması veya OpenStack uygulaması oluşturmadıysanız, bu kısım OpenStack bileşenleriyle nasıl programlama yapacağınızı öğretir.

Öğrenecekleriniz

Uygulamaları bulut ortamında kurmak geleneksel IT ortamında kurmaktan oldukça farklıdır. Bu kılavuz uygulamaları OpenStack’de nasıl kuracağınızı ve bulut uygulama geliştirme için bazı en iyi uygulamaları öğretir.

Genel görünüm

Bu öğretici iki uygulama gösterir. İlk uygulama matematiksel eşitlikler kullanarak güzel fraktal imajlar üreten bir fraktal üreticidir. Göstereceğimiz ikinci, daha sağlam uygulamayla karşılaştırabilmeniz için bu uygulamayı tamamıyla gösteriyoruz.

İkinci uygulama şunları yapmanızı sağlayacak bir OpenStack uygulamasıdır:

  • Hesaplama kaynaklarını oluşturun ve silin. Bu kaynaklar Fraktal uygulamanın çalıştığı sanal makine sunucularıdır.

  • Fonksiyonları mikro servislere döndürme ve modüler hale getirme gibi bulutla ilgili mimari kararları alın.

  • Uygun kaynakları yukarı aşağı ölçekleyin.

  • Dosya ve veritabanı kalıcılığı için Nesne ve Blok depolamayı kullanın.

  • Ortama otomatik olarak ayarlanmak için Orkestrasyon servislerini kullanın.

  • Daha iyi başarım ve ayrım için ağı özelleştirin.

  • Gelişmiş OpenStack bulut özelliklerini keşfedin ve uygulayın.

OpenStack SDK’nızı seçin

Programlama geçmişine sahip herkes bu kılavuzdaki kodu kolaylıkla okuyabilir. Bu kılavuz belirli bir SDK’ya odaklansa da, diğer dilleri ve araç takımlarını OpenStack bulutuyla kullanabilirsiniz:

OpenStack SDK’ları

Dil

Ad

Açıklama

URL

Python

OpenStack SDK

Official Python-based library for OpenStack.

https://docs.openstack.org/openstacksdk/latest/

Python

Libcloud

Apache Vakfının yönettiği Python tabanlı kitaplık. Birden çok bulut türüyle çalışmak için kullanın.

https://libcloud.readthedocs.org/en/latest/compute/drivers/openstack.html

Python

Shade

OpenStack Infra takımı tarafından geliştirilen Python tabanlı bir kitaplık. Birden çok OpenStack bulutlarını işletmek için kullanın.

https://docs.openstack.org/infra/shade/

Java

jClouds

Apache Vakfının yönettiği Java tabanlı bir kitaplık. Birden çok bulut türüyle çalışmak için kullanın.

https://jclouds.apache.org/guides/openstack/

Ruby

fog

Ruby tabanlı bir SDK. Birden çok bulutla çalışmak için kullanın.

https://github.com/fog/fog-openstack/blob/master/docs/getting_started.md

node.js

pkgcloud

Node.js tabanlı bir SDK. Birden çok bulutla çalışmak için kullanın.

https://github.com/pkgcloud/pkgcloud/tree/master/docs/providers/openstack

PHP

php-opencloud

PHP tabanlı bir kitaplık. OpenStack bulutlarıyla çalışan PHP kodu yazmak için kullanın.

http://php-opencloud.readthedocs.org/en/latest/getting-started-with-openstack.html

.NET Çatısı

Microsoft .NET için OpenStack SDK

.NET tabanlı bir kitaplık. Microsoft uygulamaları için C++ veya C# kodu yazmak için kullanın.

https://www.nuget.org/packages/openstack.net

Go

gophercloud

Go tabanlı bir SDK. OpenStack bulutlarıyla çalışan Golang kodu yazmak için kullanın.

http://gophercloud.io/

Kullanılabilir SDK listesi için, Yazılım Geliştirme Araçlarına göz atın.

Bu kılavuzun diğer sürümleri diğer SDK’ları ve dilleri kullanarak bu görevleri nasıl gerçekleştireceğinizi gösterir. Bu kılavuzda dahil edilmesini istediğiniz başka bir aracın geliştiricisi iseniz kod parçaları göndermeye çekinmeyin. Daha fazla bilgi için, OpenStack Belgelendirme takımı üyeleriyle iletişime geçin.

İhtiyacınız olan

Zaten bir OpenStack bulutuna erişiminiz olduğunu varsayıyoruz. En az altı sunucu kotasına sahip, kiracı olarak da bilinen, bir projeye sahip olmalısınız. Fraktallar uygulaması Ubuntu, Debian, Fedora-tabanlı, ve openSUSE tabanlı dağıtımlarda çalıştığından, bu işletim sistemlerinden birini kullanan sunucular oluşturmalısınız.

Bulutla iletişime geçmek için ayrıca şunlara sahip olmalısınız

libcloud 0.15.1 veya daha yenisi kurulmuş.

Aşağıdaki bilgiyi bulut sağlayıcınızdan alın:

  • yetkilendirme URL’si

  • kullanıcı adı

  • parola

  • proje kimliği veya ismi (projeler kiracılar olarak da bilinir)

  • bulut bölgesi

Ayrıca OpenStack RC dosyasını OpenStack Horizon kontrol panosundan indirebilirsiniz. Kontrol panosuna giriş yapın ve Proje->Erişim & Güvenlik->API Erişimi->OpenStack RC dosyasını indire tıklayın. Bu yöntemi kullanırsanız “yetkilendirme URL“‘sinin yolda bulunmadığını unutmayın. Örneğin openrc.sh dosyanız şöyle gösteriyorsa:

export OS_AUTH_URL=http://controller:5000/v2.0

Asıl yetkilendirme URL’si:

http://controller:5000

OpenStack ile nasıl etkileşimde bulunduğunuz

Bu öğreticide, OpenStack bulutunuzla “OpenStack SDK’nızı seçin” kısmında seçtiğiniz SDK aracılığıyla etkileşirsiniz. Bu kılavuz seçtiğiniz dilde kod parçaları çalıştırmayı bildiğinizi varsayar.

Denemek için, :code:`python -i`çağırarak aşağıdaki kodu bir Python betiğine ekleyin (veya etkileşimli Python kabuğunu kullanın).

from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver

auth_username = 'your_auth_username'
auth_password = 'your_auth_password'
auth_url = 'http://controller:5000'
project_name = 'your_project_name_or_id'
region_name = 'your_region_name'

provider = get_driver(Provider.OPENSTACK)
conn = provider(auth_username,
                auth_password,
                ex_force_auth_url=auth_url,
                ex_force_auth_version='2.0_password',
                ex_tenant_name=project_name,
                ex_force_service_region=region_name)

Not

Öğretici conn nesnesini tekrar kullandığından, hep birini el altında tuttuğunuzdan emin olun.

Not

Bu API çağrılarından birini çalıştırırken libcloud.common.types.InvalidCredsError: 'Sağlayıcıyla geçersiz kimlik bilgileri' istisnasını alırsanız, kimlik bilgilerinizi tekrar kontrol edin.

Not

Sağlayıcınız bölgeleri desteklemiyorsa, region_name için boş bir karakter dizisi (‘’) deneyin.

Nitelikler ve imajlar

Uygulamanızı çalıştırmak için bir sunucu başlatmalısınız. Sunucu bir sanal makine olarak servis verir.

Bir sunucu başlatmak için, bir nitelik ve imaj seçersiniz. Nitelik sunucunuzun boyutunu, CPU sayısı ve RAM ve disk boyutu da dahil olarak temsil eder. İmaj sunucunuzu kopyaladığınız hazır bir işletim sistemi kurulumudur. Açık bir bulutta sunucularınız önyüklediğinizde, büyük nitelikler kaynakça ve maddi olarak küçük olanlardan daha pahalı olabilir.

Bulutunuzda kullanılabilir imajları listelemek için, bazı API çağrıları çalıştırın:

images = conn.list_images()
for image in images:
    print(image)

Bu kod şu şekilde çıktı verir:

<NodeImage: id=2cccbea0-cea9-4f86-a3ed-065c652adda5, name=ubuntu-14.04, driver=OpenStack  ...>
<NodeImage: id=f2a8dadc-7c7b-498f-996a-b5272c715e55, name=cirros-0.3.3-x86_64, driver=OpenStack  ...>

Ayrıca kullanılabilir niteliklerle ilgili bilgi alabilirsiniz:

flavors = conn.list_sizes()
for flavor in flavors:
    print(flavor)

Bu kod şu şekilde çıktı verir:

<OpenStackNodeSize: id=1, name=m1.tiny, ram=512, disk=1, bandwidth=None, price=0.0, driver=OpenStack, vcpus=1,  ...>
<OpenStackNodeSize: id=2, name=m1.small, ram=2048, disk=20, bandwidth=None, price=0.0, driver=OpenStack, vcpus=1,  ...>
<OpenStackNodeSize: id=3, name=m1.medium, ram=4096, disk=40, bandwidth=None, price=0.0, driver=OpenStack, vcpus=2,  ...>
<OpenStackNodeSize: id=4, name=m1.large, ram=8192, disk=80, bandwidth=None, price=0.0, driver=OpenStack, vcpus=4,  ...>
<OpenStackNodeSize: id=5, name=m1.xlarge, ram=16384, disk=160, bandwidth=None, price=0.0, driver=OpenStack, vcpus=8,  ...>

Tabi imaj ve nitelikleriniz farklı olacaktır.

Sunucunuz için bir imaj ve nitelik seçin. 1GB kadar RAM, 1 CPU ve 1GB diske ihtiyacınız var. Bu örnek güvenli bir seçim olan, küçük nitelikte bir Ubuntu imajını kullanır. Bu kılavuzdaki ilerleyen öğretici kısımlarda imaj ve nitelik kimliklerini seçtiğiniz imaj ve niteliklere göre değiştirmeniz gerekecek.

İstediğiniz imaj bulutunuzda değilse, genellikle bulutunuzun ilke ayarlarına göre bir tane yükleyebilirsiniz. İmaj yüklemeyle ilgili bilgi için imajları elde etmeye göz atın.

İmaj ve boyut değişkenlerini bulutunuz için uygun değerlere ayarlayın. Bu değişkenleri ilerleyen kısımlarda kullanacağız.

Önce, bağlantıya önceki kısımda seçtiğiniz imajın kimliğini kullanarak belirtilen imajı almasını söyleyin:

image_id = '2cccbea0-cea9-4f86-a3ed-065c652adda5'
image = conn.get_image(image_id)
print(image)

Bu kod şu şekilde çıktı verir:

<NodeImage: id=2cccbea0-cea9-4f86-a3ed-065c652adda5, name=ubuntu-14.04, driver=OpenStack  ...>

Ardından betiğe kullanmak istediğiniz niteliği söyleyin:

flavor_id = '2'
flavor = conn.ex_get_size(flavor_id)
print(flavor)

Bu kod şu şekilde çıktı verir:

<OpenStackNodeSize: id=2, name=m1.small, ram=2048, disk=20, bandwidth=None, price=0.0, driver=OpenStack, vcpus=1,  ...>

Şimdi sunucuyu başlatabilirsiniz.

Sunucu Başlat

Sunucu oluşturmak için seçtiğiniz imajı ve niteliği kullanın.

Not

Aşağıdaki sunucu oluşturma örneği tek kiracılı bir ağa sahip olduğunuzu varsayar. ‘İstisna: 400 Kötü İstek Birden fazla muhtemel ağ bulundu, daha belirleyici olmak için bir Ağ Kimliği kullanın’ hatası alırsanız birden fazla kiracılı ağınız var demektir. Sunucuyu oluşturan çağrıya bir networks parametresi eklemeniz gerekir. Ayrıntılar için bkz Ek.

Sunucuyu oluşturun.

Not

SDK’nız sunucuya ‘düğüm’ ya da ‘makine’ diyebilir.

instance_name = 'testing'
testing_instance = conn.create_node(name=instance_name, image=image, size=flavor)
print(testing_instance)

Bu kod şu şekilde çıktı verir:

<Node: uuid=1242d56cac5bcd4c110c60d57ccdbff086515133, name=testing, state=PENDING, public_ips=[], private_ips=[], provider=OpenStack ...>

Mevcut sunucuları listelerseniz:

instances = conn.list_nodes()
for instance in instances:
    print(instance)

Yeni sunucu belirir.

<Node: uuid=1242d56cac5bcd4c110c60d57ccdbff086515133, name=testing, state=RUNNING, public_ips=[], private_ips=[], provider=OpenStack ...>

Devam etmeden önce bir şey daha yapmalısınız.

Bir sunucuyu silin

Bulut kaynakları, örneğin artık kullanmadığınız çalışan sunucular, para harcayabilir. İstenmeyen masraflardan kaçınmak için bulut kaynaklarını silin.

conn.destroy_node(testing_instance)

Sunucuları tekrar listelerseniz, sunucu kaybolacaktır.

Bu kısımda başka bir sunucu kurulumunda kullanmak için kabuğunuzu açık tutun.

Uygulamayı yeni bir sunucuya kurun

Artık sunucuları nasıl oluşturup sileceğinizi bildiğinize göre, aynı uygulamayı kurabilirsiniz. Uygulama için oluşturduğunuz sunucu oluşturduğunuz ilk sunucuya benzerdir ama bu sefer bir kaç ek kavramı devreye sokacağız.

Not

Uygulamayı indirmek için bulut sunucunuzdan internet bağlantısı gereklidir.

Uygulama için bir sunucu oluşturduğunuzda, az önce oluşturduğunuz ve sildiğiniz boş sunucudan biraz daha fazla bilgi vermek istersiniz. İlerleyen kısımlarda daha fazla ayrıntıya gireceğiz, ama şimdilik sunucuyu beslemek için sadece basitçe aşağıdaki kaynakları oluşturun:

  • Bir anahtar çifti. Sunucunuza erişmek için, OpenStack’e SSH açık anahtarını aktararak anahtar çifti oluşturmalısınız. OpenStack bu anahtar çiftini yeni sunucuya yükler. Genellikle açık anahtarınız .ssh/id_rsa.pub konumuna yazılır. SSH açık anahtarı dosyanız yoksa önce şu yönergeleri takip edin. Bu yönergeleri Fraktallar uygulama mimarisine giriş da daha derin işleyeceğiz.

Aşağıdaki örnekte, pub_key_file’yi açık SSH anahtarı dosyanızın konumuna ayarlayın.

Not

Bir IOError görürseniz, ~/.ssh/ konumunu /home/{USERNAME}/.ssh/ şeklinde mutlak yolla değiştirmeniz gerekebilir.

print('Checking for existing SSH key pair...')
keypair_name = 'demokey'
pub_key_file = '~/.ssh/id_rsa.pub'
keypair_exists = False
for keypair in conn.list_key_pairs():
    if keypair.name == keypair_name:
        keypair_exists = True

if keypair_exists:
    print('Keypair ' + keypair_name + ' already exists. Skipping import.')
else:
    print('adding keypair...')
    conn.import_key_pair_from_file(keypair_name, pub_key_file)

for keypair in conn.list_key_pairs():
    print(keypair)

<KeyPair name=demokey fingerprint=aa:bb:cc... driver=OpenStack>
  • Ağ erişimi. Öntanımlı olarak, OpenStack tüm trafiği süzer. Bir güvenlik grubu oluşturmalı ve bunu sunucunuza uygulamalısınız. Güvenlik grubu HTTP ve SSH erişimine izin verir. Fraktallar uygulama mimarisine giriş da ayrıntıya gireceğiz.

print('Checking for existing security group...')
security_group_name = 'all-in-one'
security_group_exists = False
for security_group in conn.ex_list_security_groups():
    if security_group.name == security_group_name:
        all_in_one_security_group = security_group
        security_group_exists = True

if security_group_exists:
    print('Security Group ' + all_in_one_security_group.name + ' already exists. Skipping creation.')
else:
    all_in_one_security_group = conn.ex_create_security_group(security_group_name, 'network access for all-in-one application.')
    conn.ex_create_security_group_rule(all_in_one_security_group, 'TCP', 80, 80)
    conn.ex_create_security_group_rule(all_in_one_security_group, 'TCP', 22, 22)

for security_group in conn.ex_list_security_groups():
    print(security_group)

  • Kullanıcıverisi. Sunucu oluşturma anında, OpenStack’in sunucular önyüklendikten sonra yapılandırabilmesi için kullanıcı verisi sağlayabilirsiniz. Cloud-init servisi kullanıcı verisini sunucuya uygular. Seçtiğiniz imaja cloud-init servisini önceden yüklemelisiniz. Fraktallar uygulama mimarisine giriş kısmında daha ayrıntıya gireceğiz.

userdata = '''#!/usr/bin/env bash
curl -L -s https://opendev.org/openstack/faafo/raw/contrib/install.sh | bash -s -- \
    -i faafo -i messaging -r api -r worker -r demo
'''

Artık sunucuyu önyükleyip yapılandırabilirsiniz.

Bir sunucu önyükleyin ve yapılandırın

Sunucuyu oluşturmak için imajı, niteliği, anahtar çiftini ve kullanıcı verisini kullanın. Sunucu isteği yaptıktan sonra inşa edilmesini bekleyin.

print('Checking for existing instance...')
instance_name = 'all-in-one'
instance_exists = False
for instance in conn.list_nodes():
    if instance.name == instance_name:
        testing_instance = instance
        instance_exists = True

if instance_exists:
    print('Instance ' + testing_instance.name + ' already exists. Skipping creation.')
else:
    testing_instance = conn.create_node(name=instance_name,
                                        image=image,
                                        size=flavor,
                                        ex_keyname=keypair_name,
                                        ex_userdata=userdata,
                                        ex_security_groups=[all_in_one_security_group])
    conn.wait_until_running([testing_instance])

for instance in conn.list_nodes():
    print(instance)

Sunucu önyüklendiğinde, ex_userdata değişken değeri sunucuya Fraktal uygulamasını kurmasını söyler.

Harici bağlantı için bir değişken IP ilişkilendirin

kısmında ağın ayrıntılarını kapsıyoruz.

Uygulamayı çalışır görmek için, nereye bakacağınızı bilmeniz gerekir. Öntanımlı olarak sunucunuzun dışarı ağ erişimi bulunur. Sunucunuzu internetten erişilebilir yapmak için bir IP adresine ihtiyacınız vardır. Bazı durumlarda öntanımlı olarak sunucunuz açıkça yönlendirilebilir bir IP adresiyle hazırlanır. Bu durumda sunucuları listelediğinizde public_ips veya private_ips altında listelenen bir IP adresi görürsünüz. Görmezseniz sunucunuz için bir değişken IP adresi oluşturmalı ve atamalısınız.

Sunucunuza özel bir IP adresinin atanıp atanmadığını görmek için:

private_ip = None
if len(testing_instance.private_ips):
    private_ip = testing_instance.private_ips[0]
    print('Private IP found: {}'.format(private_ip))

Eğer atanmışsa, kullanıcılar bazı OpenStack bulutlarında sunucuya erişmek için bu adresi kullanabilirler.

Sunucunuza bir açık IP adresinin atanıp atanmadığını anlamak için:

public_ip = None
if len(testing_instance.public_ips):
    public_ip = testing_instance.public_ips[0]
    print('Public IP found: {}'.format(public_ip))

Eğer atanmışsa, kullanıcılar sunucuya erişmek için bu adresi kullanabilirler.

Sunucunuzla kullanmak üzere bir değişken IP adresi oluşturmak için:

ex_list_floating_ip_pools() kullanın ve ilk değişken IP adresi havuzunu seçin. Bu havuzu projenize ayırın ve bir değişken IP adresi almak için kullanın.

print('Checking for unused Floating IP...')
unused_floating_ip = None
for floating_ip in conn.ex_list_floating_ips():
    if not floating_ip.node_id:
        unused_floating_ip = floating_ip
        break

if not unused_floating_ip and len(conn.ex_list_floating_ip_pools()):
    pool = conn.ex_list_floating_ip_pools()[0]
    print('Allocating new Floating IP from pool: {}'.format(pool))
    unused_floating_ip = pool.create_floating_ip()

Bu kod değişken IP adresini döndürür:

<OpenStack_1_1_FloatingIpAddress: id=4536ed1e-4374-4d7f-b02c-c3be2cb09b67, ip_addr=203.0.113.101, pool=<OpenStack_1_1_FloatingIpPool: name=floating001>, driver=<libcloud.compute.drivers.openstack.OpenStack_1_1_NodeDriver object at 0x1310b50>>

Attach the floating IP address to the instance:
if public_ip:
    print('Instance ' + testing_instance.name + ' already has a public ip. Skipping attachment.')
elif unused_floating_ip:
    conn.ex_attach_floating_ip_to_node(testing_instance, unused_floating_ip)

Kurulumu başlatmak için betiği çalıştırın.

Uygulamaya erişin

Uygulama verisinin ve yapılandırmanın sunucuya kurulumu biraz zaman alabilir. Beklerken bir kahve keyfi yapmayı düşünebilirsiniz. Uygulama kurulduktan sonra, tercih ettiğiniz tarayıcıyla aşağıdaki bağlantıdaki muhteşem grafik arayüzü ziyaret edebilirsiniz.

actual_ip_address = None
if public_ip:
    actual_ip_address = public_ip
elif unused_floating_ip:
    actual_ip_address = unused_floating_ip.ip_address
elif private_ip:
    actual_ip_address = private_ip

print('The Fractals app will be deployed to http://{}'.format(actual_ip_address))

Not

Değişken IP adresleri kullanmazsanız, uygun şekilde başka bir IP adresiyle değiştirin.

screenshot of the webinterface

Sonraki adımlar

Bu kavramlar henüz tam oturmadıysa endişe etmeyin. Fraktallar uygulama mimarisine giriş kısmında bu kavramları daha ayrıntılı işleyeceğiz.

Tam kod örneği

Aşağıdaki dosya öğreticinin bu kısmındaki tüm kodu içerir. Bu kapsayıcı kod örneği kodu tek bir betik olarak görüntüleme ve çalıştırma şansı verir.

Bu betiği çalıştırmadan önce, kimlik doğrulama bilgisini, nitelik ve imaj kimliğini ayarladığınızdan emin olun.

# step-1
from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver

auth_username = 'your_auth_username'
auth_password = 'your_auth_password'
auth_url = 'http://controller:5000'
project_name = 'your_project_name_or_id'
region_name = 'your_region_name'

provider = get_driver(Provider.OPENSTACK)
conn = provider(auth_username,
                auth_password,
                ex_force_auth_url=auth_url,
                ex_force_auth_version='2.0_password',
                ex_tenant_name=project_name,
                ex_force_service_region=region_name)

# step-2
images = conn.list_images()
for image in images:
    print(image)

# step-3
flavors = conn.list_sizes()
for flavor in flavors:
    print(flavor)

# step-4
image_id = '2cccbea0-cea9-4f86-a3ed-065c652adda5'
image = conn.get_image(image_id)
print(image)

# step-5
flavor_id = '2'
flavor = conn.ex_get_size(flavor_id)
print(flavor)

# step-6
instance_name = 'testing'
testing_instance = conn.create_node(name=instance_name, image=image, size=flavor)
print(testing_instance)

# step-7
instances = conn.list_nodes()
for instance in instances:
    print(instance)

# step-8
conn.destroy_node(testing_instance)

# step-9
print('Checking for existing SSH key pair...')
keypair_name = 'demokey'
pub_key_file = '~/.ssh/id_rsa.pub'
keypair_exists = False
for keypair in conn.list_key_pairs():
    if keypair.name == keypair_name:
        keypair_exists = True

if keypair_exists:
    print('Keypair ' + keypair_name + ' already exists. Skipping import.')
else:
    print('adding keypair...')
    conn.import_key_pair_from_file(keypair_name, pub_key_file)

for keypair in conn.list_key_pairs():
    print(keypair)

# step-10
print('Checking for existing security group...')
security_group_name = 'all-in-one'
security_group_exists = False
for security_group in conn.ex_list_security_groups():
    if security_group.name == security_group_name:
        all_in_one_security_group = security_group
        security_group_exists = True

if security_group_exists:
    print('Security Group ' + all_in_one_security_group.name + ' already exists. Skipping creation.')
else:
    all_in_one_security_group = conn.ex_create_security_group(security_group_name, 'network access for all-in-one application.')
    conn.ex_create_security_group_rule(all_in_one_security_group, 'TCP', 80, 80)
    conn.ex_create_security_group_rule(all_in_one_security_group, 'TCP', 22, 22)

for security_group in conn.ex_list_security_groups():
    print(security_group)

# step-11
userdata = '''#!/usr/bin/env bash
curl -L -s https://opendev.org/openstack/faafo/raw/contrib/install.sh | bash -s -- \
    -i faafo -i messaging -r api -r worker -r demo
'''

# step-12
print('Checking for existing instance...')
instance_name = 'all-in-one'
instance_exists = False
for instance in conn.list_nodes():
    if instance.name == instance_name:
        testing_instance = instance
        instance_exists = True

if instance_exists:
    print('Instance ' + testing_instance.name + ' already exists. Skipping creation.')
else:
    testing_instance = conn.create_node(name=instance_name,
                                        image=image,
                                        size=flavor,
                                        ex_keyname=keypair_name,
                                        ex_userdata=userdata,
                                        ex_security_groups=[all_in_one_security_group])
    conn.wait_until_running([testing_instance])

for instance in conn.list_nodes():
    print(instance)

# step-13
private_ip = None
if len(testing_instance.private_ips):
    private_ip = testing_instance.private_ips[0]
    print('Private IP found: {}'.format(private_ip))

# step-14
public_ip = None
if len(testing_instance.public_ips):
    public_ip = testing_instance.public_ips[0]
    print('Public IP found: {}'.format(public_ip))

# step-15
print('Checking for unused Floating IP...')
unused_floating_ip = None
for floating_ip in conn.ex_list_floating_ips():
    if not floating_ip.node_id:
        unused_floating_ip = floating_ip
        break

if not unused_floating_ip and len(conn.ex_list_floating_ip_pools()):
    pool = conn.ex_list_floating_ip_pools()[0]
    print('Allocating new Floating IP from pool: {}'.format(pool))
    unused_floating_ip = pool.create_floating_ip()

# step-16
if public_ip:
    print('Instance ' + testing_instance.name + ' already has a public ip. Skipping attachment.')
elif unused_floating_ip:
    conn.ex_attach_floating_ip_to_node(testing_instance, unused_floating_ip)

# step-17
actual_ip_address = None
if public_ip:
    actual_ip_address = public_ip
elif unused_floating_ip:
    actual_ip_address = unused_floating_ip.ip_address
elif private_ip:
    actual_ip_address = private_ip

print('The Fractals app will be deployed to http://{}'.format(actual_ip_address))
Creative Commons Attribution 3.0 License

Except where otherwise noted, this document is licensed under Creative Commons Attribution 3.0 License. See all OpenStack Legal Documents.