├── .fixtures.yml ├── .gitattributes ├── .gitignore ├── .pdkignore ├── .puppet-lint.rc ├── .rspec ├── .rubocop.yml ├── .rubocop_todo.yml ├── .sync.yml ├── .vscode └── extensions.json ├── .yardopts ├── CHANGELOG.md ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── data └── common.yaml ├── hiera.yaml ├── hue.rb ├── lib └── puppet │ ├── provider │ ├── hue.rb │ └── hue_light │ │ └── rest.rb │ └── type │ └── hue_light.rb ├── manifests └── init.pp ├── metadata.json ├── pdk.yaml ├── rakelib └── acceptance.rake ├── samples ├── blue.pp ├── effect.pp ├── green.pp ├── hue_light.rb ├── no_effect.pp ├── red.pp └── rest.rb └── spec ├── acceptance ├── hue_light_spec.rb └── nodesets │ └── default.yml ├── default_facts.yml ├── spec_helper.rb └── spec_helper_acceptance.rb /.fixtures.yml: -------------------------------------------------------------------------------- 1 | # This file can be used to install module dependencies for unit testing 2 | # See https://github.com/puppetlabs/puppetlabs_spec_helper#using-fixtures for details 3 | --- 4 | fixtures: 5 | forge_modules: 6 | # stdlib: "puppetlabs/stdlib" 7 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.rb eol=lf 2 | *.erb eol=lf 3 | *.pp eol=lf 4 | *.sh eol=lf 5 | *.epp eol=lf 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .git/ 2 | .*.sw[op] 3 | .metadata 4 | .yardoc 5 | .yardwarns 6 | *.iml 7 | /.bundle/ 8 | /.idea/ 9 | /.vagrant/ 10 | /coverage/ 11 | /bin/ 12 | /doc/ 13 | /Gemfile.local 14 | /Gemfile.lock 15 | /junit/ 16 | /log/ 17 | /pkg/ 18 | /spec/fixtures/manifests/ 19 | /spec/fixtures/modules/* 20 | /tmp/ 21 | /vendor/ 22 | /convert_report.txt 23 | /update_report.txt 24 | .DS_Store 25 | .project 26 | .envrc 27 | /inventory.yaml 28 | /spec/fixtures/litmus_inventory.yaml 29 | -------------------------------------------------------------------------------- /.pdkignore: -------------------------------------------------------------------------------- 1 | .git/ 2 | .*.sw[op] 3 | .metadata 4 | .yardoc 5 | .yardwarns 6 | *.iml 7 | /.bundle/ 8 | /.idea/ 9 | /.vagrant/ 10 | /coverage/ 11 | /bin/ 12 | /doc/ 13 | /Gemfile.local 14 | /Gemfile.lock 15 | /junit/ 16 | /log/ 17 | /pkg/ 18 | /spec/fixtures/manifests/ 19 | /spec/fixtures/modules/* 20 | /tmp/ 21 | /vendor/ 22 | /convert_report.txt 23 | /update_report.txt 24 | .DS_Store 25 | .project 26 | .envrc 27 | /inventory.yaml 28 | /spec/fixtures/litmus_inventory.yaml 29 | /.fixtures.yml 30 | /Gemfile 31 | /.gitattributes 32 | /.github/ 33 | /.gitignore 34 | /.pdkignore 35 | /.puppet-lint.rc 36 | /Rakefile 37 | /rakelib/ 38 | /.rspec 39 | /..yml 40 | /.yardopts 41 | /spec/ 42 | /.vscode/ 43 | /.sync.yml 44 | /.devcontainer/ 45 | -------------------------------------------------------------------------------- /.puppet-lint.rc: -------------------------------------------------------------------------------- 1 | --relative 2 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --format documentation 3 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | require: 3 | - rubocop-performance 4 | - rubocop-rspec 5 | AllCops: 6 | NewCops: enable 7 | DisplayCopNames: true 8 | TargetRubyVersion: '2.6' 9 | Include: 10 | - "**/*.rb" 11 | Exclude: 12 | - bin/* 13 | - ".vendor/**/*" 14 | - "**/Gemfile" 15 | - "**/Rakefile" 16 | - pkg/**/* 17 | - spec/fixtures/**/* 18 | - vendor/**/* 19 | - "**/Puppetfile" 20 | - "**/Vagrantfile" 21 | - "**/Guardfile" 22 | Layout/LineLength: 23 | Description: People have wide screens, use them. 24 | Max: 200 25 | RSpec/BeforeAfterAll: 26 | Description: Beware of using after(:all) as it may cause state to leak between tests. 27 | A necessary evil in acceptance testing. 28 | Exclude: 29 | - spec/acceptance/**/*.rb 30 | RSpec/HookArgument: 31 | Description: Prefer explicit :each argument, matching existing module's style 32 | EnforcedStyle: each 33 | RSpec/DescribeSymbol: 34 | Exclude: 35 | - spec/unit/facter/**/*.rb 36 | Style/BlockDelimiters: 37 | Description: Prefer braces for chaining. Mostly an aesthetical choice. Better to 38 | be consistent then. 39 | EnforcedStyle: braces_for_chaining 40 | Style/ClassAndModuleChildren: 41 | Description: Compact style reduces the required amount of indentation. 42 | EnforcedStyle: compact 43 | Style/EmptyElse: 44 | Description: Enforce against empty else clauses, but allow `nil` for clarity. 45 | EnforcedStyle: empty 46 | Style/FormatString: 47 | Description: Following the main puppet project's style, prefer the % format format. 48 | EnforcedStyle: percent 49 | Style/FormatStringToken: 50 | Description: Following the main puppet project's style, prefer the simpler template 51 | tokens over annotated ones. 52 | EnforcedStyle: template 53 | Style/Lambda: 54 | Description: Prefer the keyword for easier discoverability. 55 | EnforcedStyle: literal 56 | Style/RegexpLiteral: 57 | Description: Community preference. See https://github.com/voxpupuli/modulesync_config/issues/168 58 | EnforcedStyle: percent_r 59 | Style/TernaryParentheses: 60 | Description: Checks for use of parentheses around ternary conditions. Enforce parentheses 61 | on complex expressions for better readability, but seriously consider breaking 62 | it up. 63 | EnforcedStyle: require_parentheses_when_complex 64 | Style/TrailingCommaInArguments: 65 | Description: Prefer always trailing comma on multiline argument lists. This makes 66 | diffs, and re-ordering nicer. 67 | EnforcedStyleForMultiline: comma 68 | Style/TrailingCommaInArrayLiteral: 69 | Description: Prefer always trailing comma on multiline literals. This makes diffs, 70 | and re-ordering nicer. 71 | EnforcedStyleForMultiline: comma 72 | Style/SymbolArray: 73 | Description: Using percent style obscures symbolic intent of array's contents. 74 | EnforcedStyle: brackets 75 | RSpec/MessageSpies: 76 | EnforcedStyle: receive 77 | Style/Documentation: 78 | Exclude: 79 | - lib/puppet/parser/functions/**/* 80 | - spec/**/* 81 | Style/WordArray: 82 | EnforcedStyle: brackets 83 | Performance/AncestorsInclude: 84 | Enabled: true 85 | Performance/BigDecimalWithNumericArgument: 86 | Enabled: true 87 | Performance/BlockGivenWithExplicitBlock: 88 | Enabled: true 89 | Performance/CaseWhenSplat: 90 | Enabled: true 91 | Performance/ConstantRegexp: 92 | Enabled: true 93 | Performance/MethodObjectAsBlock: 94 | Enabled: true 95 | Performance/RedundantSortBlock: 96 | Enabled: true 97 | Performance/RedundantStringChars: 98 | Enabled: true 99 | Performance/ReverseFirst: 100 | Enabled: true 101 | Performance/SortReverse: 102 | Enabled: true 103 | Performance/Squeeze: 104 | Enabled: true 105 | Performance/StringInclude: 106 | Enabled: true 107 | Performance/Sum: 108 | Enabled: true 109 | Style/CollectionMethods: 110 | Enabled: true 111 | Style/MethodCalledOnDoEndBlock: 112 | Enabled: true 113 | Style/StringMethods: 114 | Enabled: true 115 | Bundler/GemFilename: 116 | Enabled: false 117 | Bundler/InsecureProtocolSource: 118 | Enabled: false 119 | Capybara/CurrentPathExpectation: 120 | Enabled: false 121 | Capybara/VisibilityMatcher: 122 | Enabled: false 123 | Gemspec/DuplicatedAssignment: 124 | Enabled: false 125 | Gemspec/OrderedDependencies: 126 | Enabled: false 127 | Gemspec/RequiredRubyVersion: 128 | Enabled: false 129 | Gemspec/RubyVersionGlobalsUsage: 130 | Enabled: false 131 | Layout/ArgumentAlignment: 132 | Enabled: false 133 | Layout/BeginEndAlignment: 134 | Enabled: false 135 | Layout/ClosingHeredocIndentation: 136 | Enabled: false 137 | Layout/EmptyComment: 138 | Enabled: false 139 | Layout/EmptyLineAfterGuardClause: 140 | Enabled: false 141 | Layout/EmptyLinesAroundArguments: 142 | Enabled: false 143 | Layout/EmptyLinesAroundAttributeAccessor: 144 | Enabled: false 145 | Layout/EndOfLine: 146 | Enabled: false 147 | Layout/FirstArgumentIndentation: 148 | Enabled: false 149 | Layout/HashAlignment: 150 | Enabled: false 151 | Layout/HeredocIndentation: 152 | Enabled: false 153 | Layout/LeadingEmptyLines: 154 | Enabled: false 155 | Layout/SpaceAroundMethodCallOperator: 156 | Enabled: false 157 | Layout/SpaceInsideArrayLiteralBrackets: 158 | Enabled: false 159 | Layout/SpaceInsideReferenceBrackets: 160 | Enabled: false 161 | Lint/BigDecimalNew: 162 | Enabled: false 163 | Lint/BooleanSymbol: 164 | Enabled: false 165 | Lint/ConstantDefinitionInBlock: 166 | Enabled: false 167 | Lint/DeprecatedOpenSSLConstant: 168 | Enabled: false 169 | Lint/DisjunctiveAssignmentInConstructor: 170 | Enabled: false 171 | Lint/DuplicateElsifCondition: 172 | Enabled: false 173 | Lint/DuplicateRequire: 174 | Enabled: false 175 | Lint/DuplicateRescueException: 176 | Enabled: false 177 | Lint/EmptyConditionalBody: 178 | Enabled: false 179 | Lint/EmptyFile: 180 | Enabled: false 181 | Lint/ErbNewArguments: 182 | Enabled: false 183 | Lint/FloatComparison: 184 | Enabled: false 185 | Lint/HashCompareByIdentity: 186 | Enabled: false 187 | Lint/IdentityComparison: 188 | Enabled: false 189 | Lint/InterpolationCheck: 190 | Enabled: false 191 | Lint/MissingCopEnableDirective: 192 | Enabled: false 193 | Lint/MixedRegexpCaptureTypes: 194 | Enabled: false 195 | Lint/NestedPercentLiteral: 196 | Enabled: false 197 | Lint/NonDeterministicRequireOrder: 198 | Enabled: false 199 | Lint/OrderedMagicComments: 200 | Enabled: false 201 | Lint/OutOfRangeRegexpRef: 202 | Enabled: false 203 | Lint/RaiseException: 204 | Enabled: false 205 | Lint/RedundantCopEnableDirective: 206 | Enabled: false 207 | Lint/RedundantRequireStatement: 208 | Enabled: false 209 | Lint/RedundantSafeNavigation: 210 | Enabled: false 211 | Lint/RedundantWithIndex: 212 | Enabled: false 213 | Lint/RedundantWithObject: 214 | Enabled: false 215 | Lint/RegexpAsCondition: 216 | Enabled: false 217 | Lint/ReturnInVoidContext: 218 | Enabled: false 219 | Lint/SafeNavigationConsistency: 220 | Enabled: false 221 | Lint/SafeNavigationWithEmpty: 222 | Enabled: false 223 | Lint/SelfAssignment: 224 | Enabled: false 225 | Lint/SendWithMixinArgument: 226 | Enabled: false 227 | Lint/ShadowedArgument: 228 | Enabled: false 229 | Lint/StructNewOverride: 230 | Enabled: false 231 | Lint/ToJSON: 232 | Enabled: false 233 | Lint/TopLevelReturnWithArgument: 234 | Enabled: false 235 | Lint/TrailingCommaInAttributeDeclaration: 236 | Enabled: false 237 | Lint/UnreachableLoop: 238 | Enabled: false 239 | Lint/UriEscapeUnescape: 240 | Enabled: false 241 | Lint/UriRegexp: 242 | Enabled: false 243 | Lint/UselessMethodDefinition: 244 | Enabled: false 245 | Lint/UselessTimes: 246 | Enabled: false 247 | Metrics/AbcSize: 248 | Enabled: false 249 | Metrics/BlockLength: 250 | Enabled: false 251 | Metrics/BlockNesting: 252 | Enabled: false 253 | Metrics/ClassLength: 254 | Enabled: false 255 | Metrics/CyclomaticComplexity: 256 | Enabled: false 257 | Metrics/MethodLength: 258 | Enabled: false 259 | Metrics/ModuleLength: 260 | Enabled: false 261 | Metrics/ParameterLists: 262 | Enabled: false 263 | Metrics/PerceivedComplexity: 264 | Enabled: false 265 | Migration/DepartmentName: 266 | Enabled: false 267 | Naming/AccessorMethodName: 268 | Enabled: false 269 | Naming/BlockParameterName: 270 | Enabled: false 271 | Naming/HeredocDelimiterCase: 272 | Enabled: false 273 | Naming/HeredocDelimiterNaming: 274 | Enabled: false 275 | Naming/MemoizedInstanceVariableName: 276 | Enabled: false 277 | Naming/MethodParameterName: 278 | Enabled: false 279 | Naming/RescuedExceptionsVariableName: 280 | Enabled: false 281 | Naming/VariableNumber: 282 | Enabled: false 283 | Performance/BindCall: 284 | Enabled: false 285 | Performance/DeletePrefix: 286 | Enabled: false 287 | Performance/DeleteSuffix: 288 | Enabled: false 289 | Performance/InefficientHashSearch: 290 | Enabled: false 291 | Performance/UnfreezeString: 292 | Enabled: false 293 | Performance/UriDefaultParser: 294 | Enabled: false 295 | RSpec/Be: 296 | Enabled: false 297 | RSpec/Capybara/FeatureMethods: 298 | Enabled: false 299 | RSpec/ContainExactly: 300 | Enabled: false 301 | RSpec/ContextMethod: 302 | Enabled: false 303 | RSpec/ContextWording: 304 | Enabled: false 305 | RSpec/DescribeClass: 306 | Enabled: false 307 | RSpec/EmptyHook: 308 | Enabled: false 309 | RSpec/EmptyLineAfterExample: 310 | Enabled: false 311 | RSpec/EmptyLineAfterExampleGroup: 312 | Enabled: false 313 | RSpec/EmptyLineAfterHook: 314 | Enabled: false 315 | RSpec/ExampleLength: 316 | Enabled: false 317 | RSpec/ExampleWithoutDescription: 318 | Enabled: false 319 | RSpec/ExpectChange: 320 | Enabled: false 321 | RSpec/ExpectInHook: 322 | Enabled: false 323 | RSpec/FactoryBot/AttributeDefinedStatically: 324 | Enabled: false 325 | RSpec/FactoryBot/CreateList: 326 | Enabled: false 327 | RSpec/FactoryBot/FactoryClassName: 328 | Enabled: false 329 | RSpec/HooksBeforeExamples: 330 | Enabled: false 331 | RSpec/ImplicitBlockExpectation: 332 | Enabled: false 333 | RSpec/ImplicitSubject: 334 | Enabled: false 335 | RSpec/LeakyConstantDeclaration: 336 | Enabled: false 337 | RSpec/LetBeforeExamples: 338 | Enabled: false 339 | RSpec/MatchArray: 340 | Enabled: false 341 | RSpec/MissingExampleGroupArgument: 342 | Enabled: false 343 | RSpec/MultipleExpectations: 344 | Enabled: false 345 | RSpec/MultipleMemoizedHelpers: 346 | Enabled: false 347 | RSpec/MultipleSubjects: 348 | Enabled: false 349 | RSpec/NestedGroups: 350 | Enabled: false 351 | RSpec/PredicateMatcher: 352 | Enabled: false 353 | RSpec/ReceiveCounts: 354 | Enabled: false 355 | RSpec/ReceiveNever: 356 | Enabled: false 357 | RSpec/RepeatedExampleGroupBody: 358 | Enabled: false 359 | RSpec/RepeatedExampleGroupDescription: 360 | Enabled: false 361 | RSpec/RepeatedIncludeExample: 362 | Enabled: false 363 | RSpec/ReturnFromStub: 364 | Enabled: false 365 | RSpec/SharedExamples: 366 | Enabled: false 367 | RSpec/StubbedMock: 368 | Enabled: false 369 | RSpec/UnspecifiedException: 370 | Enabled: false 371 | RSpec/VariableDefinition: 372 | Enabled: false 373 | RSpec/VoidExpect: 374 | Enabled: false 375 | RSpec/Yield: 376 | Enabled: false 377 | Security/Open: 378 | Enabled: false 379 | Style/AccessModifierDeclarations: 380 | Enabled: false 381 | Style/AccessorGrouping: 382 | Enabled: false 383 | Style/BisectedAttrAccessor: 384 | Enabled: false 385 | Style/CaseLikeIf: 386 | Enabled: false 387 | Style/ClassEqualityComparison: 388 | Enabled: false 389 | Style/ColonMethodDefinition: 390 | Enabled: false 391 | Style/CombinableLoops: 392 | Enabled: false 393 | Style/CommentedKeyword: 394 | Enabled: false 395 | Style/Dir: 396 | Enabled: false 397 | Style/DoubleCopDisableDirective: 398 | Enabled: false 399 | Style/EmptyBlockParameter: 400 | Enabled: false 401 | Style/EmptyLambdaParameter: 402 | Enabled: false 403 | Style/Encoding: 404 | Enabled: false 405 | Style/EvalWithLocation: 406 | Enabled: false 407 | Style/ExpandPathArguments: 408 | Enabled: false 409 | Style/ExplicitBlockArgument: 410 | Enabled: false 411 | Style/ExponentialNotation: 412 | Enabled: false 413 | Style/FloatDivision: 414 | Enabled: false 415 | Style/FrozenStringLiteralComment: 416 | Enabled: false 417 | Style/GlobalStdStream: 418 | Enabled: false 419 | Style/HashAsLastArrayItem: 420 | Enabled: false 421 | Style/HashLikeCase: 422 | Enabled: false 423 | Style/HashTransformKeys: 424 | Enabled: false 425 | Style/HashTransformValues: 426 | Enabled: false 427 | Style/IfUnlessModifier: 428 | Enabled: false 429 | Style/KeywordParametersOrder: 430 | Enabled: false 431 | Style/MinMax: 432 | Enabled: false 433 | Style/MixinUsage: 434 | Enabled: false 435 | Style/MultilineWhenThen: 436 | Enabled: false 437 | Style/NegatedUnless: 438 | Enabled: false 439 | Style/NumericPredicate: 440 | Enabled: false 441 | Style/OptionalBooleanParameter: 442 | Enabled: false 443 | Style/OrAssignment: 444 | Enabled: false 445 | Style/RandomWithOffset: 446 | Enabled: false 447 | Style/RedundantAssignment: 448 | Enabled: false 449 | Style/RedundantCondition: 450 | Enabled: false 451 | Style/RedundantConditional: 452 | Enabled: false 453 | Style/RedundantFetchBlock: 454 | Enabled: false 455 | Style/RedundantFileExtensionInRequire: 456 | Enabled: false 457 | Style/RedundantRegexpCharacterClass: 458 | Enabled: false 459 | Style/RedundantRegexpEscape: 460 | Enabled: false 461 | Style/RedundantSelfAssignment: 462 | Enabled: false 463 | Style/RedundantSort: 464 | Enabled: false 465 | Style/RescueStandardError: 466 | Enabled: false 467 | Style/SingleArgumentDig: 468 | Enabled: false 469 | Style/SlicingWithRange: 470 | Enabled: false 471 | Style/SoleNestedConditional: 472 | Enabled: false 473 | Style/StderrPuts: 474 | Enabled: false 475 | Style/StringConcatenation: 476 | Enabled: false 477 | Style/Strip: 478 | Enabled: false 479 | Style/SymbolProc: 480 | Enabled: false 481 | Style/TrailingBodyOnClass: 482 | Enabled: false 483 | Style/TrailingBodyOnMethodDefinition: 484 | Enabled: false 485 | Style/TrailingBodyOnModule: 486 | Enabled: false 487 | Style/TrailingCommaInHashLiteral: 488 | Enabled: false 489 | Style/TrailingMethodEndStatement: 490 | Enabled: false 491 | Style/UnpackFirst: 492 | Enabled: false 493 | Capybara/MatchStyle: 494 | Enabled: false 495 | Capybara/NegationMatcher: 496 | Enabled: false 497 | Capybara/SpecificActions: 498 | Enabled: false 499 | Capybara/SpecificFinders: 500 | Enabled: false 501 | Capybara/SpecificMatcher: 502 | Enabled: false 503 | Gemspec/DeprecatedAttributeAssignment: 504 | Enabled: false 505 | Gemspec/DevelopmentDependencies: 506 | Enabled: false 507 | Gemspec/RequireMFA: 508 | Enabled: false 509 | Layout/LineContinuationLeadingSpace: 510 | Enabled: false 511 | Layout/LineContinuationSpacing: 512 | Enabled: false 513 | Layout/LineEndStringConcatenationIndentation: 514 | Enabled: false 515 | Layout/SpaceBeforeBrackets: 516 | Enabled: false 517 | Lint/AmbiguousAssignment: 518 | Enabled: false 519 | Lint/AmbiguousOperatorPrecedence: 520 | Enabled: false 521 | Lint/AmbiguousRange: 522 | Enabled: false 523 | Lint/ConstantOverwrittenInRescue: 524 | Enabled: false 525 | Lint/DeprecatedConstants: 526 | Enabled: false 527 | Lint/DuplicateBranch: 528 | Enabled: false 529 | Lint/DuplicateMagicComment: 530 | Enabled: false 531 | Lint/DuplicateMatchPattern: 532 | Enabled: false 533 | Lint/DuplicateRegexpCharacterClassElement: 534 | Enabled: false 535 | Lint/EmptyBlock: 536 | Enabled: false 537 | Lint/EmptyClass: 538 | Enabled: false 539 | Lint/EmptyInPattern: 540 | Enabled: false 541 | Lint/IncompatibleIoSelectWithFiberScheduler: 542 | Enabled: false 543 | Lint/LambdaWithoutLiteralBlock: 544 | Enabled: false 545 | Lint/NoReturnInBeginEndBlocks: 546 | Enabled: false 547 | Lint/NonAtomicFileOperation: 548 | Enabled: false 549 | Lint/NumberedParameterAssignment: 550 | Enabled: false 551 | Lint/OrAssignmentToConstant: 552 | Enabled: false 553 | Lint/RedundantDirGlobSort: 554 | Enabled: false 555 | Lint/RefinementImportMethods: 556 | Enabled: false 557 | Lint/RequireRangeParentheses: 558 | Enabled: false 559 | Lint/RequireRelativeSelfPath: 560 | Enabled: false 561 | Lint/SymbolConversion: 562 | Enabled: false 563 | Lint/ToEnumArguments: 564 | Enabled: false 565 | Lint/TripleQuotes: 566 | Enabled: false 567 | Lint/UnexpectedBlockArity: 568 | Enabled: false 569 | Lint/UnmodifiedReduceAccumulator: 570 | Enabled: false 571 | Lint/UselessRescue: 572 | Enabled: false 573 | Lint/UselessRuby2Keywords: 574 | Enabled: false 575 | Metrics/CollectionLiteralLength: 576 | Enabled: false 577 | Naming/BlockForwarding: 578 | Enabled: false 579 | Performance/CollectionLiteralInLoop: 580 | Enabled: false 581 | Performance/ConcurrentMonotonicTime: 582 | Enabled: false 583 | Performance/MapCompact: 584 | Enabled: false 585 | Performance/RedundantEqualityComparisonBlock: 586 | Enabled: false 587 | Performance/RedundantSplitRegexpArgument: 588 | Enabled: false 589 | Performance/StringIdentifierArgument: 590 | Enabled: false 591 | RSpec/BeEq: 592 | Enabled: false 593 | RSpec/BeNil: 594 | Enabled: false 595 | RSpec/ChangeByZero: 596 | Enabled: false 597 | RSpec/ClassCheck: 598 | Enabled: false 599 | RSpec/DuplicatedMetadata: 600 | Enabled: false 601 | RSpec/ExcessiveDocstringSpacing: 602 | Enabled: false 603 | RSpec/FactoryBot/ConsistentParenthesesStyle: 604 | Enabled: false 605 | RSpec/FactoryBot/FactoryNameStyle: 606 | Enabled: false 607 | RSpec/FactoryBot/SyntaxMethods: 608 | Enabled: false 609 | RSpec/IdenticalEqualityAssertion: 610 | Enabled: false 611 | RSpec/NoExpectationExample: 612 | Enabled: false 613 | RSpec/PendingWithoutReason: 614 | Enabled: false 615 | RSpec/Rails/AvoidSetupHook: 616 | Enabled: false 617 | RSpec/Rails/HaveHttpStatus: 618 | Enabled: false 619 | RSpec/Rails/InferredSpecType: 620 | Enabled: false 621 | RSpec/Rails/MinitestAssertions: 622 | Enabled: false 623 | RSpec/Rails/TravelAround: 624 | Enabled: false 625 | RSpec/RedundantAround: 626 | Enabled: false 627 | RSpec/SkipBlockInsideExample: 628 | Enabled: false 629 | RSpec/SortMetadata: 630 | Enabled: false 631 | RSpec/SubjectDeclaration: 632 | Enabled: false 633 | RSpec/VerifiedDoubleReference: 634 | Enabled: false 635 | Security/CompoundHash: 636 | Enabled: false 637 | Security/IoMethods: 638 | Enabled: false 639 | Style/ArgumentsForwarding: 640 | Enabled: false 641 | Style/ArrayIntersect: 642 | Enabled: false 643 | Style/CollectionCompact: 644 | Enabled: false 645 | Style/ComparableClamp: 646 | Enabled: false 647 | Style/ConcatArrayLiterals: 648 | Enabled: false 649 | Style/DataInheritance: 650 | Enabled: false 651 | Style/DirEmpty: 652 | Enabled: false 653 | Style/DocumentDynamicEvalDefinition: 654 | Enabled: false 655 | Style/EmptyHeredoc: 656 | Enabled: false 657 | Style/EndlessMethod: 658 | Enabled: false 659 | Style/EnvHome: 660 | Enabled: false 661 | Style/FetchEnvVar: 662 | Enabled: false 663 | Style/FileEmpty: 664 | Enabled: false 665 | Style/FileRead: 666 | Enabled: false 667 | Style/FileWrite: 668 | Enabled: false 669 | Style/HashConversion: 670 | Enabled: false 671 | Style/HashExcept: 672 | Enabled: false 673 | Style/IfWithBooleanLiteralBranches: 674 | Enabled: false 675 | Style/InPatternThen: 676 | Enabled: false 677 | Style/MagicCommentFormat: 678 | Enabled: false 679 | Style/MapCompactWithConditionalBlock: 680 | Enabled: false 681 | Style/MapToHash: 682 | Enabled: false 683 | Style/MapToSet: 684 | Enabled: false 685 | Style/MinMaxComparison: 686 | Enabled: false 687 | Style/MultilineInPatternThen: 688 | Enabled: false 689 | Style/NegatedIfElseCondition: 690 | Enabled: false 691 | Style/NestedFileDirname: 692 | Enabled: false 693 | Style/NilLambda: 694 | Enabled: false 695 | Style/NumberedParameters: 696 | Enabled: false 697 | Style/NumberedParametersLimit: 698 | Enabled: false 699 | Style/ObjectThen: 700 | Enabled: false 701 | Style/OpenStructUse: 702 | Enabled: false 703 | Style/OperatorMethodCall: 704 | Enabled: false 705 | Style/QuotedSymbols: 706 | Enabled: false 707 | Style/RedundantArgument: 708 | Enabled: false 709 | Style/RedundantConstantBase: 710 | Enabled: false 711 | Style/RedundantDoubleSplatHashBraces: 712 | Enabled: false 713 | Style/RedundantEach: 714 | Enabled: false 715 | Style/RedundantHeredocDelimiterQuotes: 716 | Enabled: false 717 | Style/RedundantInitialize: 718 | Enabled: false 719 | Style/RedundantLineContinuation: 720 | Enabled: false 721 | Style/RedundantSelfAssignmentBranch: 722 | Enabled: false 723 | Style/RedundantStringEscape: 724 | Enabled: false 725 | Style/SelectByRegexp: 726 | Enabled: false 727 | Style/StringChars: 728 | Enabled: false 729 | Style/SwapValues: 730 | Enabled: false 731 | -------------------------------------------------------------------------------- /.rubocop_todo.yml: -------------------------------------------------------------------------------- 1 | # This configuration was generated by 2 | # `rubocop --auto-gen-config` 3 | # on 2015-10-07 12:25:07 -0700 using RuboCop version 0.34.2. 4 | # The point is for the user to remove these configuration records 5 | # one by one as the offenses are removed from the code base. 6 | # Note that changes in the inspected code, or installation of new 7 | # versions of RuboCop, may require this file to be generated again. 8 | 9 | # Offense count: 2 10 | Lint/UselessAssignment: 11 | Exclude: 12 | - 'lib/modulesync.rb' 13 | - 'lib/modulesync/cli.rb' 14 | 15 | # Offense count: 6 16 | Metrics/AbcSize: 17 | Max: 64 18 | 19 | # Offense count: 1 20 | # Configuration parameters: CountComments. 21 | Metrics/ClassLength: 22 | Max: 105 23 | 24 | # Offense count: 4 25 | Metrics/CyclomaticComplexity: 26 | Max: 13 27 | 28 | # Offense count: 29 29 | # Configuration parameters: AllowURI, URISchemes. 30 | Metrics/LineLength: 31 | Max: 319 32 | 33 | # Offense count: 8 34 | # Configuration parameters: CountComments. 35 | Metrics/MethodLength: 36 | Max: 79 37 | 38 | # Offense count: 1 39 | # Configuration parameters: CountComments. 40 | Metrics/ModuleLength: 41 | Max: 140 42 | 43 | # Offense count: 4 44 | Metrics/PerceivedComplexity: 45 | Max: 16 46 | 47 | # Offense count: 9 48 | # Configuration parameters: Exclude. 49 | Style/Documentation: 50 | Exclude: 51 | - 'lib/modulesync.rb' 52 | - 'lib/modulesync/cli.rb' 53 | - 'lib/modulesync/constants.rb' 54 | - 'lib/modulesync/git.rb' 55 | - 'lib/modulesync/hook.rb' 56 | - 'lib/modulesync/renderer.rb' 57 | - 'lib/modulesync/util.rb' 58 | 59 | # Offense count: 1 60 | Style/EachWithObject: 61 | Exclude: 62 | - 'lib/modulesync/util.rb' 63 | 64 | # Offense count: 1 65 | # Configuration parameters: MinBodyLength. 66 | Style/GuardClause: 67 | Exclude: 68 | - 'lib/modulesync/cli.rb' 69 | 70 | # Offense count: 1 71 | # Cop supports --auto-correct. 72 | # Configuration parameters: AllowAsExpressionSeparator. 73 | Style/Semicolon: 74 | Exclude: 75 | - 'lib/modulesync/util.rb' 76 | -------------------------------------------------------------------------------- /.sync.yml: -------------------------------------------------------------------------------- 1 | # This file can be used to customize the files managed by PDK. 2 | # 3 | # See https://github.com/puppetlabs/pdk-templates/blob/main/README.md 4 | # for more information. 5 | # 6 | # See https://github.com/puppetlabs/pdk-templates/blob/main/config_defaults.yml 7 | # for the default values. 8 | --- {} 9 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "puppet.puppet-vscode", 4 | "Shopify.ruby-lsp" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.yardopts: -------------------------------------------------------------------------------- 1 | --markup markdown 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.2.0 2 | * rototiller added, code cleanup, readme changes. 3 | 4 | ## 0.1.1 5 | * metadata cleanup, module cleanup. 6 | 7 | ## 0.1.0 8 | * Initial release. 9 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source ENV['GEM_SOURCE'] || 'https://rubygems.org' 2 | 3 | def location_for(place_or_version, fake_version = nil) 4 | git_url_regex = %r{\A(?(https?|git)[:@][^#]*)(#(?.*))?} 5 | file_url_regex = %r{\Afile:\/\/(?.*)} 6 | 7 | if place_or_version && (git_url = place_or_version.match(git_url_regex)) 8 | [fake_version, { git: git_url[:url], branch: git_url[:branch], require: false }].compact 9 | elsif place_or_version && (file_url = place_or_version.match(file_url_regex)) 10 | ['>= 0', { path: File.expand_path(file_url[:path]), require: false }] 11 | else 12 | [place_or_version, { require: false }] 13 | end 14 | end 15 | 16 | group :development do 17 | gem "json", '= 2.1.0', require: false if Gem::Requirement.create(['>= 2.5.0', '< 2.7.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) 18 | gem "json", '= 2.3.0', require: false if Gem::Requirement.create(['>= 2.7.0', '< 3.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) 19 | gem "json", '= 2.5.1', require: false if Gem::Requirement.create(['>= 3.0.0', '< 3.0.5']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) 20 | gem "json", '= 2.6.1', require: false if Gem::Requirement.create(['>= 3.1.0', '< 3.1.3']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) 21 | gem "json", '= 2.6.3', require: false if Gem::Requirement.create(['>= 3.2.0', '< 4.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) 22 | gem "racc", '~> 1.4.0', require: false if Gem::Requirement.create(['>= 2.7.0', '< 3.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) 23 | gem "deep_merge", '~> 1.0', require: false 24 | gem "voxpupuli-puppet-lint-plugins", '~> 5.0', require: false 25 | gem "facterdb", '~> 1.18', require: false 26 | gem "metadata-json-lint", '~> 4.0', require: false 27 | gem "rspec-puppet-facts", '~> 3.0', require: false 28 | gem "dependency_checker", '~> 1.0.0', require: false 29 | gem "parallel_tests", '= 3.12.1', require: false 30 | gem "pry", '~> 0.10', require: false 31 | gem "simplecov-console", '~> 0.9', require: false 32 | gem "puppet-debugger", '~> 1.0', require: false 33 | gem "rubocop", '~> 1.50.0', require: false 34 | gem "rubocop-performance", '= 1.16.0', require: false 35 | gem "rubocop-rspec", '= 2.19.0', require: false 36 | gem "rb-readline", '= 0.5.5', require: false, platforms: [:mswin, :mingw, :x64_mingw] 37 | end 38 | group :development, :release_prep do 39 | gem "puppet-strings", '~> 4.0', require: false 40 | gem "puppetlabs_spec_helper", '~> 7.0', require: false 41 | end 42 | group :system_tests do 43 | gem "puppet_litmus", '~> 1.0', require: false, platforms: [:ruby, :x64_mingw] 44 | gem "CFPropertyList", '< 3.0.7', require: false, platforms: [:mswin, :mingw, :x64_mingw] 45 | gem "serverspec", '~> 2.41', require: false 46 | end 47 | 48 | puppet_version = ENV['PUPPET_GEM_VERSION'] 49 | facter_version = ENV['FACTER_GEM_VERSION'] 50 | hiera_version = ENV['HIERA_GEM_VERSION'] 51 | 52 | gems = {} 53 | 54 | gems['puppet'] = location_for(puppet_version) 55 | 56 | # If facter or hiera versions have been specified via the environment 57 | # variables 58 | 59 | gems['facter'] = location_for(facter_version) if facter_version 60 | gems['hiera'] = location_for(hiera_version) if hiera_version 61 | 62 | gems.each do |gem_name, gem_params| 63 | gem gem_name, *gem_params 64 | end 65 | 66 | # Evaluate Gemfile.local and ~/.gemfile if they exist 67 | extra_gemfiles = [ 68 | "#{__FILE__}.local", 69 | File.join(Dir.home, '.gemfile'), 70 | ] 71 | 72 | extra_gemfiles.each do |gemfile| 73 | if File.file?(gemfile) && File.readable?(gemfile) 74 | eval(File.read(gemfile), binding) 75 | end 76 | end 77 | # vim: syntax=ruby 78 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # simple_hue 2 | 3 | ## Table of Contents 4 | 5 | 1. [Module Description - This module controls the Philips hue](#module-description) 6 | 2. [Setup - The basics of getting started with [modulename]](#setup) 7 | * [What simple_hue affects](#what-simple-hue-affects) 8 | * [Setup requirements](#setup-requirements) 9 | * [Beginning with simple_hue](#beginning-with-simple_hue) 10 | 3. [Usage - Configuration options and additional functionality](#usage) 11 | 4. [Reference - An under-the-hood peek at what the module is doing and how](#reference) 12 | 5. [Limitations - OS compatibility, etc.](#limitations) 13 | 6. [Development - Guide for contributing to the module](#development) 14 | 7. [Feedback - Get in touch !](#feedback) 15 | 16 | ## Module description 17 | 18 | The philips Hue is a hub that controls wirelessly connected lightbulbs. This module allows you to connect to the hub and control the lightbulbs. The purpose of this module is for teaching, and providing a simple framework to start development with. simple_hue will not get any new features, the smart_hue module exposes more features in the philips hue. 19 | 20 | ## Setup 21 | 22 | ### What simple hue affects 23 | 24 | -Changes the state of light bulbs connected to the philips hue. 25 | 26 | ### Setup requirements 27 | 28 | * a philips hue hub 29 | * a philips hue light bulb or compatible 30 | * a puppet agent 31 | 32 | ### Beginning with simple_hue 33 | 34 | These two attributes are needed for puppet to control the philips hue hub: 35 | DEVELOPER_KEY: Grab a developer key from your hue hub, follow the steps here: http://www.developers.meethue.com/documentation/getting-started 36 | DEVELOPER_ID: Find the IP / hostname of your hue hub. Use a uPNP scanner, Nmap, your router / DHCP logs. 37 | 38 | We use environment variables to store this. On a Ubuntu box we would set them like 39 | export HUE_KEY=pUAUbcowosjBKgE5VQTrD6kkfkfoQK1ZtN14pHl8; export HUE_IP=10.64.12.162 40 | 41 | ## Usage 42 | 43 | Your puppet manifest file that turns the first light on would look something like: 44 | hue_light { '1': 45 | on => 'true', 46 | hue => '0', 47 | } 48 | 49 | To apply the manifest run the following (you will need to have set some environment variables mentioned above) 50 | 51 | puppet apply manifest.pp 52 | 53 | ### Query the hue hub 54 | 55 | Run the following: (you will need to have set some environment variables mentioned above) 56 | puppet resource hue_light 57 | 58 | ## Reference 59 | 60 | * All API calls are made using the ruby faraday library. 61 | * We follow the type / provider idiom. 62 | * This is agentless. 63 | * Followed this API guide: http://www.developers.meethue.com/documentation/lights-api#11_get_all_lights 64 | 65 | ## Limitations 66 | 67 | There are no known limitations. Currently only tested on Ubuntu, developed on the mac. 68 | 69 | ## Development 70 | 71 | This is a simple module designed for teaching, this is not the place for new features. Fixes or improvements to hat is already here, are welcome. 72 | 73 | ### Running the acceptance tests 74 | 75 | - Get virtual box installed 76 | - Get vagrant installed 77 | - clone the repo `git@github.com:tphoney/simple_hue.git` 78 | - grab the necessary gems `bundle install --path .bundle/gems/` 79 | - run `bundle exec rake acceptance` and set the necessary environment variables 80 | - profit !!! 81 | 82 | ### Stopping the VM from dissapearing when the tests run 83 | 84 | - alternately run 'BEAKER_provision=yes BEAKER_destroy=no bundle exec rspec spec/acceptance' NB make sure the environment variables are set 85 | 86 | ## Feedback 87 | 88 | Feel free to leave issues or PR's on the github page. 89 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'bundler' 4 | require 'puppet_litmus/rake_tasks' if Gem.loaded_specs.key? 'puppet_litmus' 5 | require 'puppetlabs_spec_helper/rake_tasks' 6 | require 'puppet-syntax/tasks/puppet-syntax' 7 | require 'puppet-strings/tasks' if Gem.loaded_specs.key? 'puppet-strings' 8 | 9 | PuppetLint.configuration.send('disable_relative') 10 | -------------------------------------------------------------------------------- /data/common.yaml: -------------------------------------------------------------------------------- 1 | --- {} 2 | -------------------------------------------------------------------------------- /hiera.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 5 3 | 4 | defaults: # Used for any hierarchy level that omits these keys. 5 | datadir: data # This path is relative to hiera.yaml's directory. 6 | data_hash: yaml_data # Use the built-in YAML backend. 7 | 8 | hierarchy: 9 | - name: "osfamily/major release" 10 | paths: 11 | # Used to distinguish between Debian and Ubuntu 12 | - "os/%{facts.os.name}/%{facts.os.release.major}.yaml" 13 | - "os/%{facts.os.family}/%{facts.os.release.major}.yaml" 14 | # Used for Solaris 15 | - "os/%{facts.os.family}/%{facts.kernelrelease}.yaml" 16 | - name: "osfamily" 17 | paths: 18 | - "os/%{facts.os.name}.yaml" 19 | - "os/%{facts.os.family}.yaml" 20 | - name: 'common' 21 | path: 'common.yaml' 22 | -------------------------------------------------------------------------------- /hue.rb: -------------------------------------------------------------------------------- 1 | #!/opt/puppetlabs/puppet/bin/ruby 2 | require 'json' 3 | require 'uri' 4 | require 'faraday' 5 | require 'pry' 6 | require 'optparse' 7 | 8 | options = {} 9 | 10 | # sends the command to the hue hub and checks for errors 11 | def send_command(ip, url, key, message) 12 | connection = Faraday.new(url: "http://#{ip}/api/#{key}", ssl: { verify: false }) 13 | response = connection.put(url, message.to_json) 14 | return unless response.status != 200 || response.body.include?('error') 15 | raise("Error sending command.\nuri: #{url}\nmessage: #{message}\nresponse: #{response.body}") 16 | end 17 | 18 | def alert(ip, bulb_number, key) 19 | url = "lights/#{bulb_number}/state" 20 | message = { 'alert' => 'lselect' } 21 | send_command(ip, url, key, message) 22 | end 23 | 24 | def color(ip, bulb_number, key, color) 25 | url = "lights/#{bulb_number}/state" 26 | hue = if color == 'red' 27 | 0 28 | elsif color == 'blue' 29 | 46_920 30 | elsif color == 'green' 31 | 46_920 32 | else 33 | color.to_i 34 | end 35 | message = { 'hue' => hue } 36 | send_command(ip, url, key, message) 37 | end 38 | 39 | def brightness(ip, bulb_number, key, brightness) 40 | # TODO: Complete this function 41 | end 42 | 43 | parser = OptionParser.new do |opts| 44 | opts.banner = 'Usage: hue.rb [options]' 45 | 46 | opts.on('-i', '--ip NAME', 'IP address of the hue hub. Required.') { |v| options[:ip] = v } 47 | opts.on('-k', '--key KEY', 'Auth key for hub API. Required') { |v| options[:key] = v } 48 | opts.on('-n', '--bulb_number NUMBER', 'bulb number. Required') { |v| options[:bulb_number] = v } 49 | opts.on('-c', '--color COLOR', 'change color can be a number 0-65535 or pick red|green|blue') { |v| options[:color] = v } 50 | opts.on('-b', '--brightness NUMBER', 'change brighness 0-254') { |v| options[:brightness] = v } 51 | opts.on('-a', '--alert', 'send an alert') { |_v| options[:alert] = true } 52 | end 53 | 54 | parser.parse! 55 | if options.empty? 56 | puts parser 57 | exit 58 | end 59 | 60 | if options[:ip].nil? 61 | puts 'ERROR: No IP Address specified.' 62 | puts 'Use --help to find info on command line arguments.' 63 | exit 64 | end 65 | 66 | if options[:key].nil? 67 | puts 'ERROR: No API Key specified.' 68 | puts 'Use --help to find info on command line arguments.' 69 | exit 70 | end 71 | 72 | if options[:bulb_number].nil? 73 | puts 'ERROR: No bulb number specified.' 74 | puts 'Use --help to find info on command line arguments.' 75 | exit 76 | end 77 | 78 | if options[:alert] 79 | alert(options[:ip], options[:bulb_number], options[:key]) 80 | end 81 | if options[:color] 82 | color(options[:ip], options[:bulb_number], options[:key], options[:color]) 83 | end 84 | if options[:brightness] 85 | brightness(options[:ip], options[:bulb_number], options[:key], options[:brightness]) 86 | end 87 | -------------------------------------------------------------------------------- /lib/puppet/provider/hue.rb: -------------------------------------------------------------------------------- 1 | require 'json' 2 | require 'uri' 3 | require 'faraday' 4 | 5 | # This is the base class on which other providers are based. 6 | class Puppet::Provider::Hue < Puppet::Provider 7 | def initialize(value = {}) 8 | super(value) 9 | @original_values = if value.is_a? Hash 10 | value.clone 11 | else 12 | {} 13 | end 14 | @create_elements = false 15 | end 16 | 17 | def self.prefetch(resources) 18 | nodes = instances 19 | resources.each_key do |name| 20 | if provider = nodes.find { |node| node.name == name } # rubocop:disable all 21 | resources[name].provider = provider 22 | end 23 | end 24 | end 25 | 26 | def exists? 27 | @property_hash[:ensure] == :present 28 | end 29 | 30 | def self.connection 31 | raise('HUE_IP environment variable is not set, set using \'export HUE_IP=1.1.1.1\' where 1.1.1.1 is the ip of your hue hub') if ENV['HUE_IP'].nil? 32 | hue_ip = ENV['HUE_IP'] 33 | raise('HUE_KEY environment variable is not set, set using \'export HUE_KEY=key_thing\' where key_thing is a developer key for your hue hub') if ENV['HUE_KEY'].nil? 34 | hue_key = ENV['HUE_KEY'] 35 | @connection = Faraday.new(url: "http://#{hue_ip}/api/#{hue_key}", ssl: { verify: false }) 36 | end 37 | 38 | def self.hue_get(url, args = nil) 39 | url = URI.escape(url) if url 40 | result = connection.get(url, args) 41 | output = JSON.parse(result.body) 42 | output 43 | rescue JSON::ParserError 44 | nil 45 | end 46 | 47 | def self.hue_put(url, message) 48 | message = message.to_json 49 | message.gsub!(%r{"false"}, 'false') 50 | message.gsub!(%r{"true"}, 'true') 51 | connection.put(url, message) 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /lib/puppet/provider/hue_light/rest.rb: -------------------------------------------------------------------------------- 1 | require 'puppet/provider/hue' 2 | 3 | Puppet::Type.type(:hue_light).provide(:rest, parent: Puppet::Provider::Hue) do 4 | confine feature: :posix 5 | defaultfor feature: :posix 6 | 7 | mk_resource_methods 8 | 9 | def self.instances 10 | instances = [] 11 | lights = Puppet::Provider::Hue.hue_get('lights') 12 | 13 | return [] if lights.nil? 14 | 15 | lights.each do |light| 16 | instances << new(name: light.first, 17 | on: light.last['state']['on'].to_s, 18 | bri: light.last['state']['bri'].to_s, 19 | hue: light.last['state']['hue'].to_s) 20 | end 21 | 22 | instances 23 | end 24 | 25 | def flush 26 | name = @original_values[:name] 27 | @property_hash = @property_hash.select { |k, _v| resource[k] } 28 | @property_hash.delete(:name) 29 | @property_hash[:hue] = @property_hash[:hue].to_i 30 | @property_hash[:bri] = @property_hash[:bri].to_i 31 | Puppet::Provider::Hue.hue_put("lights/#{name}/state", @property_hash) 32 | end 33 | 34 | def create 35 | raise('Create not supported.') 36 | end 37 | 38 | def destroy 39 | notice('Destroy not supported.') 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /lib/puppet/type/hue_light.rb: -------------------------------------------------------------------------------- 1 | Puppet::Type.newtype(:hue_light) do 2 | newparam(:name) do 3 | desc 'The light name' 4 | isnamevar 5 | end 6 | 7 | newproperty(:on) do 8 | desc 'is the light on' 9 | end 10 | 11 | newproperty(:hue) do 12 | desc 'hue of the hue_light' 13 | end 14 | 15 | newproperty(:bri) do 16 | desc 'brightness of the hue_light' 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /manifests/init.pp: -------------------------------------------------------------------------------- 1 | # no need for anything here 2 | class simple_hue { 3 | } 4 | -------------------------------------------------------------------------------- /metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tphoney-simple_hue", 3 | "version": "0.2.1", 4 | "author": "tphoney", 5 | "summary": "A puppet module that controls the philips hue. It is designed for teaching purposes.", 6 | "license": "Apache-2.0", 7 | "source": "https://github.com/tphoney/simple_hue", 8 | "project_page": "https://github.com/tphoney/simple_hue", 9 | "issues_url": "https://github.com/tphoney/simple_hue/issues", 10 | "dependencies": [ 11 | 12 | ], 13 | "operatingsystem_support": [ 14 | { 15 | "operatingsystem": "Ubuntu", 16 | "operatingsystemrelease": [ 17 | "10.04", 18 | "12.04", 19 | "14.04" 20 | ] 21 | } 22 | ], 23 | "requirements": [ 24 | { 25 | "name": "puppet", 26 | "version_requirement": ">=4.0.0 <5.0.0" 27 | } 28 | ], 29 | "tags": [ 30 | "simple_hue", 31 | "philips", 32 | "hue", 33 | "learning module", 34 | "example module", 35 | "IOT", 36 | "REST", 37 | "JSON" 38 | ], 39 | "pdk-version": "3.2.0", 40 | "template-url": "pdk-default#3.2.0", 41 | "template-ref": "tags/3.2.0-0-gb257ef1" 42 | } 43 | -------------------------------------------------------------------------------- /pdk.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ignore: [] 3 | -------------------------------------------------------------------------------- /rakelib/acceptance.rake: -------------------------------------------------------------------------------- 1 | require 'rake' 2 | require 'rototiller' 3 | # We clear the Beaker rake tasks from spec_helper as they assume 4 | # rspec-puppet and a certain filesystem layout 5 | Rake::Task[:beaker_nodes].clear 6 | Rake::Task[:beaker].clear 7 | 8 | rototiller_task :spec_prep do |t| 9 | t.add_env({:name => 'BEAKER_PE_DIR', 10 | :message => 'Puppet Enterprise source directory', 11 | :default => 'http://enterprise.delivery.puppetlabs.net/2015.3/preview/'}) 12 | 13 | t.add_env({:name => 'BEAKER_debug', 14 | :message => 'Beaker debug level', 15 | :default => 'false'}) 16 | 17 | t.add_env({:name => 'BEAKER_set', 18 | :message => 'Beaker set. This defines what beaker nodeset will be used for the test', 19 | :default => "default"}) 20 | 21 | t.add_env({:name => 'BEAKER_keyfile', 22 | :message => 'The keyfile is the rsa pem file used to connect to the vm test instances', 23 | :default => '~/.ssh/id_rsa-acceptance'}) 24 | 25 | t.add_env({:name => 'HUE_IP', 26 | :message => 'HUE_IP environment variable is not set, set using \'export HUE_IP=1.1.1.1\' where 1.1.1.1 is the ip of your hue hub', 27 | }) 28 | 29 | t.add_env({:name => 'HUE_KEY', 30 | :message => 'HUE_KEY environment variable is not set, set using \'export HUE_KEY=key_thing\' where key_thing is a developer key for your hue hub', 31 | }) 32 | end 33 | 34 | 35 | desc "Run acceptance tests" 36 | RSpec::Core::RakeTask.new(:acceptance => [:spec_prep]) do |t| 37 | t.pattern = 'spec/acceptance' 38 | end 39 | -------------------------------------------------------------------------------- /samples/blue.pp: -------------------------------------------------------------------------------- 1 | hue_light { '1': 2 | bri => '254', 3 | hue => '46920', 4 | on => 'true', 5 | } 6 | hue_light { '2': 7 | bri => '254', 8 | hue => '46920', 9 | on => 'true', 10 | } 11 | -------------------------------------------------------------------------------- /samples/effect.pp: -------------------------------------------------------------------------------- 1 | hue_light { '1': 2 | effect => 'colorloop', 3 | hue => '46920', 4 | on => 'true', 5 | } 6 | hue_light { '2': 7 | effect => 'colorloop', 8 | hue => '46920', 9 | on => 'true', 10 | } 11 | -------------------------------------------------------------------------------- /samples/green.pp: -------------------------------------------------------------------------------- 1 | hue_light { '1': 2 | bri => '254', 3 | hue => '25500', 4 | on => 'true', 5 | } 6 | hue_light { '2': 7 | bri => '254', 8 | hue => '25500', 9 | on => 'true', 10 | } 11 | -------------------------------------------------------------------------------- /samples/hue_light.rb: -------------------------------------------------------------------------------- 1 | Puppet::Type.newtype(:hue_light) do 2 | newparam(:name) do 3 | desc 'The light name' 4 | isnamevar 5 | end 6 | 7 | newproperty(:on) do 8 | desc 'is the light on' 9 | end 10 | 11 | newproperty(:hue) do 12 | desc 'hue of the hue_light' 13 | end 14 | 15 | newproperty(:bri) do 16 | desc 'brightness of the hue_light' 17 | end 18 | 19 | newproperty(:effect) do 20 | desc 'effect of the hue_light' 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /samples/no_effect.pp: -------------------------------------------------------------------------------- 1 | hue_light { '1': 2 | bri => '254', 3 | effect => 'none', 4 | hue => '46920', 5 | on => 'true', 6 | } 7 | hue_light { '2': 8 | bri => '254', 9 | effect => 'none', 10 | hue => '46920', 11 | on => 'true', 12 | } 13 | -------------------------------------------------------------------------------- /samples/red.pp: -------------------------------------------------------------------------------- 1 | hue_light { '1': 2 | bri => '254', 3 | hue => '0', 4 | on => 'true', 5 | } 6 | hue_light { '2': 7 | bri => '254', 8 | hue => '0', 9 | on => 'true', 10 | } 11 | -------------------------------------------------------------------------------- /samples/rest.rb: -------------------------------------------------------------------------------- 1 | require 'puppet/provider/hue' 2 | 3 | Puppet::Type.type(:hue_light).provide(:rest, parent: Puppet::Provider::Hue) do 4 | confine feature: :posix 5 | defaultfor feature: :posix 6 | 7 | mk_resource_methods 8 | 9 | def self.instances 10 | instances = [] 11 | lights = Puppet::Provider::Hue.hue_get('lights') 12 | 13 | return [] if lights.nil? 14 | 15 | lights.each do |light| 16 | instances << new(name: light.first, 17 | on: light.last['state']['on'].to_s, 18 | bri: light.last['state']['bri'].to_s, 19 | effect: light.last['state']['effect'].to_s, 20 | hue: light.last['state']['hue'].to_s) 21 | end 22 | 23 | instances 24 | end 25 | 26 | def flush 27 | name = @original_values[:name] 28 | @property_hash = @property_hash.select { |k, _v| resource[k] } 29 | @property_hash.delete(:name) 30 | @property_hash[:hue] = @property_hash[:hue].to_i 31 | @property_hash[:bri] = @property_hash[:bri].to_i 32 | @property_hash[:effect] = @property_hash[:effect] 33 | Puppet::Provider::Hue.hue_put("lights/#{name}/state", @property_hash) 34 | end 35 | 36 | def create 37 | raise('Create not supported.') 38 | end 39 | 40 | def destroy 41 | notice('Destroy not supported.') 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /spec/acceptance/hue_light_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper_acceptance' 2 | describe 'should change the hue_light' do 3 | it 'turn the light on and set hue to red' do 4 | pp = <<-EOS 5 | hue_light { '1': 6 | bri => '254', 7 | hue => '0', 8 | on => 'true', 9 | } 10 | EOS 11 | Beaker::TestmodeSwitcher::DSL.execute_manifest(pp, beaker_opts) 12 | result = Beaker::TestmodeSwitcher::DSL.execute_manifest(pp, beaker_opts) 13 | # Are we idempotent 14 | expect(result.exit_code).to eq 0 15 | 16 | # Check puppet resource 17 | result = Beaker::TestmodeSwitcher::DSL.resource('hue_light', '1', beaker_opts) 18 | expect(result.stdout).to match(%r{hue => '0'}) 19 | expect(result.stdout).to match(%r{bri => '254'}) 20 | expect(result.stdout).to match(%r{on => 'true'}) 21 | end 22 | 23 | it 'sets the hue to blue' do 24 | pp = <<-EOS 25 | hue_light { '1': 26 | bri => '254', 27 | hue => '46920', 28 | } 29 | EOS 30 | Beaker::TestmodeSwitcher::DSL.execute_manifest(pp, beaker_opts) 31 | result = Beaker::TestmodeSwitcher::DSL.execute_manifest(pp, beaker_opts) 32 | # Are we idempotent 33 | expect(result.exit_code).to eq 0 34 | 35 | # Check puppet resource 36 | result = Beaker::TestmodeSwitcher::DSL.resource('hue_light', '1', beaker_opts) 37 | match(%r{bri => '254'}) 38 | expect(result.stdout).to match(%r{hue => '46920'}) 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /spec/acceptance/nodesets/default.yml: -------------------------------------------------------------------------------- 1 | HOSTS: 2 | huemaster: 3 | roles: 4 | - default 5 | - master 6 | - dashboard 7 | - database 8 | platform: ubuntu-14.04-amd64 9 | box : puppetlabs/ubuntu-14.04-64-nocm 10 | box_url : https://vagrantcloud.com/puppetlabs/ubuntu-14.04-64-nocm 11 | hypervisor : vagrant 12 | CONFIG: 13 | type: foss 14 | log_level: debug 15 | color: false 16 | consoleport: 443 17 | pe_dir: http://neptune.puppetlabs.lan/2015.2/ci-ready/ 18 | -------------------------------------------------------------------------------- /spec/default_facts.yml: -------------------------------------------------------------------------------- 1 | # Use default_module_facts.yml for module specific facts. 2 | # 3 | # Facts specified here will override the values provided by rspec-puppet-facts. 4 | --- 5 | networking: 6 | ip: "172.16.254.254" 7 | ip6: "FE80:0000:0000:0000:AAAA:AAAA:AAAA" 8 | mac: "AA:AA:AA:AA:AA:AA" 9 | is_pe: false 10 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.configure do |c| 4 | c.mock_with :rspec 5 | end 6 | 7 | require 'puppetlabs_spec_helper/module_spec_helper' 8 | require 'rspec-puppet-facts' 9 | 10 | require 'spec_helper_local' if File.file?(File.join(File.dirname(__FILE__), 'spec_helper_local.rb')) 11 | 12 | include RspecPuppetFacts 13 | 14 | default_facts = { 15 | puppetversion: Puppet.version, 16 | facterversion: Facter.version, 17 | } 18 | 19 | default_fact_files = [ 20 | File.expand_path(File.join(File.dirname(__FILE__), 'default_facts.yml')), 21 | File.expand_path(File.join(File.dirname(__FILE__), 'default_module_facts.yml')), 22 | ] 23 | 24 | default_fact_files.each do |f| 25 | next unless File.exist?(f) && File.readable?(f) && File.size?(f) 26 | 27 | begin 28 | require 'deep_merge' 29 | default_facts.deep_merge!(YAML.safe_load(File.read(f), permitted_classes: [], permitted_symbols: [], aliases: true)) 30 | rescue StandardError => e 31 | RSpec.configuration.reporter.message "WARNING: Unable to load #{f}: #{e}" 32 | end 33 | end 34 | 35 | # read default_facts and merge them over what is provided by facterdb 36 | default_facts.each do |fact, value| 37 | add_custom_fact fact, value, merge_facts: true 38 | end 39 | 40 | RSpec.configure do |c| 41 | c.default_facts = default_facts 42 | c.before :each do 43 | # set to strictest setting for testing 44 | # by default Puppet runs at warning level 45 | Puppet.settings[:strict] = :warning 46 | Puppet.settings[:strict_variables] = true 47 | end 48 | c.filter_run_excluding(bolt: true) unless ENV['GEM_BOLT'] 49 | c.after(:suite) do 50 | RSpec::Puppet::Coverage.report!(0) 51 | end 52 | 53 | # Filter backtrace noise 54 | backtrace_exclusion_patterns = [ 55 | %r{spec_helper}, 56 | %r{gems}, 57 | ] 58 | 59 | if c.respond_to?(:backtrace_exclusion_patterns) 60 | c.backtrace_exclusion_patterns = backtrace_exclusion_patterns 61 | elsif c.respond_to?(:backtrace_clean_patterns) 62 | c.backtrace_clean_patterns = backtrace_exclusion_patterns 63 | end 64 | end 65 | 66 | # Ensures that a module is defined 67 | # @param module_name Name of the module 68 | def ensure_module_defined(module_name) 69 | module_name.split('::').reduce(Object) do |last_module, next_module| 70 | last_module.const_set(next_module, Module.new) unless last_module.const_defined?(next_module, false) 71 | last_module.const_get(next_module, false) 72 | end 73 | end 74 | 75 | # 'spec_overrides' from sync.yml will appear below this line 76 | -------------------------------------------------------------------------------- /spec/spec_helper_acceptance.rb: -------------------------------------------------------------------------------- 1 | require 'master_manipulator' 2 | require 'beaker' 3 | require 'beaker-rspec' if ENV['BEAKER_TESTMODE'] != 'local' 4 | require 'beaker/puppet_install_helper' 5 | require 'beaker/testmode_switcher/dsl' 6 | 7 | run_puppet_install_helper 8 | hue_ip = ENV['HUE_IP'] 9 | hue_key = ENV['HUE_KEY'] 10 | 11 | def beaker_opts 12 | @env ||= { 13 | debug: true, 14 | trace: true, 15 | environment: { 16 | 'HUE_IP' => ENV['HUE_IP'], 17 | 'HUE_KEY' => ENV['HUE_KEY'], 18 | } 19 | } 20 | end 21 | 22 | RSpec.configure do |c| 23 | c.before :suite do 24 | unless ENV['BEAKER_TESTMODE'] == 'local' 25 | unless ENV['BEAKER_provision'] == 'no' 26 | 27 | hosts.each do |host| 28 | on(host, 'apt-get install -y vim') 29 | on(host, '/opt/puppetlabs/puppet/bin/gem install faraday') 30 | on(host, '/opt/puppetlabs/puppet/bin/gem install pry') 31 | on(host, "echo export HUE_KEY=#{hue_key} >> /root/.bashrc") 32 | on(host, "echo export HUE_IP=#{hue_ip} >> /root/.bashrc") 33 | on(host, 'source /root/.bashrc') 34 | on(host, '. /root/.bashrc') 35 | end 36 | end 37 | 38 | proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) 39 | hosts.each do |host| 40 | install_dev_puppet_module_on(host, source: proj_root, module_name: 'hue', target_module_path: '/etc/puppetlabs/code/modules') 41 | on(host, "whoami; pwd; echo #{hue_ip}") 42 | end 43 | end 44 | end 45 | end 46 | --------------------------------------------------------------------------------