2015-10-17 4 views
0

Я хотел бы сгруппировать кучу связанного кода в класс под Fabric и вызвать функции, определенные в этом классе из командной строки.Вызов класса, а затем функции в классе в Fabric

Например, приведено несколько упрощенных псевдокодов для управления серверами Google Compute Engine.

class GoogleCloud(Task): 
    def __init__(self, zone="us-east-1c"): 
     credentials = GoogleCredentials.get_application_default() 
     self.compute = build('compute', 'v1', credentials=credentials) 
     self.project = "my_project" 
     self.zone = zone 

    def server_create(self, hostname): 
     config = { 
      'name': hostname 
     } 
     instance = self.compute.instances().insert(
      project=self.project, 
      zone=self.zone, 
      body=config).execute() 

    def server_delete(self, hostname): 
      return self.compute.instances().delete(
      project=self.project, 
      zone=self.zone, 
      instance=hostname 
      ).execute() 

То, что я хотел бы быть в состоянии сделать, это вызвать как server_create и server_delete из командной строки, например:

fab GoogleCloud.server_delete:foobar 

или даже проходящие переменные в обоих инициализации и функции ...

fab GoogleCloud:us-east1-b.server_create:new_server 

Любая идея, как это осуществить? Похоже, что это достаточно полезно, чтобы ткань поддерживала его из коробки, но я не могу понять, где она может быть задокументирована.

Конечно, реальный код является гораздо более сложным, с классами для AmazonCloud и KvmInstance и т.д.

+0

Fabric поддерживает [пространства имен] (http://docs.fabfile.org/en/1.10/usage/tasks.html#namespaces). Вы можете переместить классы задач в отдельные подмодули. – approxiblue

ответ

1

У меня есть для вас решение:

рядом с вашим fabfile.py добавить __init__.py (SUPER важно .)

добавить GoogleCloud.py

from fabric.api import task, env 

env.zone = "us-east-1c" 

@task 
def zone(zone): 
    env.zone = zone 

@task 
def server_create(hostname): 
    print('create %s on %s' % (hostname, env.zone)) 

@task 
def server_delete(hostname): 
    print('delete %s on %s' % (hostname, env.zone)) 

, то вы можете запустить:

$ fab GoogleCloud.server_delete:hello 
delete hello on us-east-1c 

Done. 
$ fab GoogleCloud.zone:other GoogleCloud.server_delete:hello 
delete hello on other 

Done. 

Вы можете сделать это классом, но я действительно не вижу смысла в том, чтобы сказать вам правду, поскольку каждая задача должна быть ее собственным классом. В любом случае, дайте мне знать. (я сохранил то же имя, которое у вас было, я предлагаю вам его изменить)