Pourquoi devrais-je utiliser une classe paramétrée marionnette?

12

Généralement, lorsque je travaille avec des modules de marionnettes complexes, je définirai des variables au niveau du nœud ou à l'intérieur d'une classe. par exemple,

node 'foo.com' {
  $file_owner = "larry" 
  include bar 
}

class bar { 
  $file_name = "larry.txt"
  include do_stuff
}

class do_stuff {
  file { $file_name:
    ensure => file,
    owner  => $file_owner,
  }
}

Comment / quand / pourquoi les classes paramétrées aident-elles quand cette situation? Comment utilisez-vous les classes paramétrées pour structurer vos modules de marionnettes?

robbyt
la source
2
Remarque pour tous ceux qui trouvent cet exemple, ce code affiche les recherches de variables globales autorisées dans Puppet version <3.0. Dans Puppet> 3.0, vous ne pouvez pas accéder aux variables hors de portée et devez utiliser l'espace de noms pour accéder aux variables. Dans cet exemple, vous devez utiliser $bar::file_nameet $::file_owneraccéder à ces variables respectives. Cependant, lors de l'utilisation de classes paramétrées, les variables transmises à une classe via les paramètres deviennent des variables de portée locale.
robbyt

Réponses:

12

Les classes paramétrées sont une construction de langage pour vous aider à mieux structurer votre code. Il vous empêche d'utiliser excessivement des variables globales (comme dans votre exemple).

Imaginez que vous incluiez 20 classes supplémentaires dans la description de votre nœud et que toutes auraient besoin que certaines variables soient définies dans la portée globale ou du nœud du manifeste. Les classes paramétrées vous permettent également d'avoir facilement des paramètres par défaut, vous pouvez donc utiliser une valeur par défaut pour le $file_ownerau lieu d'avoir à fournir la même valeur (par exemple larry) à plusieurs endroits différents.

Votre exemple d'extrait (avec deux nœuds supplémentaires) pourrait être écrit comme suit:

node 'example.com' { 
  class { bar: }
}

node 'example.net' {
  class { bar: owner = "harry" }
}

node 'example.net' {
  class { bar: file_name = "barry.txt" }
}

class bar($owner = "larry", $file_name = "larry.txt") { 
  class { do_stuff: owner => $owner, file_name => $file_name }
}

class do_stuff($owner, $file_name) {
  file { $file_name:
    ensure => file,
    owner  => $owner,
  }
}

Avec votre utilisation des variables globales, vous auriez besoin de déclarer une variable nommée $ownerdans chaque nœud et vous ne seriez pas en mesure d'écraser la $file_namevariable / paramètre par nœud. Au lieu de cela, vous devez déclarer une autre barclasse pour chaque nœud.

Le document sur l'évolution du langage de Puppet et bien sûr le guide du langage fournissent de bons exemples sur la façon d'utiliser les classes paramétrées et la logique derrière cette construction du langage:

joschi
la source
8

La meilleure façon d'y penser est d'y arriver dès le début au lieu de commencer par connaître déjà les idiomes de la marionnette.

Ce que vous essayez de faire en premier lieu, c'est de passer des paramètres à une classe - vous lui donnez les informations dont il a besoin pour décider comment se comporter, tout comme passer des arguments à une fonction. Disons que c'était perl et que vous aviez une fonction appelée multiply_squares. Vous l'appeleriez comme multiply_squares(3, 4), ne définissez pas certaines variables globales à 3 et 4, puis les lisez à l'intérieur de la fonction!

Mais historiquement, le code Puppet a dû le faire avec des variables globales ou une portée dynamique, car la nécessité de le faire est apparue avant que le langage ne soit conçu pour le faire. Personnellement, je pense qu'une fois les classes paramétrées un peu plus évoluées et plus largement déployées, elles feront essentiellement des problèmes de portée variable une chose du passé, car avoir le bon outil disponible pour le travail éliminera toute une couche de hacks effrayants.

nfagerlund
la source