{"id":16643482,"url":"https://github.com/sonots/kondate","last_synced_at":"2025-03-16T22:31:33.551Z","repository":{"id":56880404,"uuid":"46652494","full_name":"sonots/kondate","owner":"sonots","description":"Kondate is yet another nodes management framework for Itamae/Serverspec","archived":false,"fork":false,"pushed_at":"2020-06-16T14:19:27.000Z","size":98,"stargazers_count":57,"open_issues_count":3,"forks_count":4,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-04-14T11:51:21.210Z","etag":null,"topics":["itamae","ruby"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sonots.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-11-22T08:32:59.000Z","updated_at":"2024-01-17T17:40:20.000Z","dependencies_parsed_at":"2022-08-20T23:40:18.099Z","dependency_job_id":null,"html_url":"https://github.com/sonots/kondate","commit_stats":null,"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sonots%2Fkondate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sonots%2Fkondate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sonots%2Fkondate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sonots%2Fkondate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sonots","download_url":"https://codeload.github.com/sonots/kondate/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243832255,"owners_count":20355074,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["itamae","ruby"],"created_at":"2024-10-12T08:08:41.390Z","updated_at":"2025-03-16T22:31:33.221Z","avatar_url":"https://github.com/sonots.png","language":"Ruby","readme":"# Kondate\n\nKondate is yet another nodes management framework for Itamae/Serverspec.\n\nKondate provides nodes/roles/attributes/run_lists management feature for Itamae/Serverspec.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'kondate'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install kondate\n\n## Usage\n\nGenerate a template directory tree:\n\n```\n$ bundle exec kondate init .\n```\n\nRun itamae:\n\n```\n$ bundle exec kondate itamae \u003chost\u003e\n```\n\nRun serverspec:\n\n```\n$ bundle exec kondate serverspec \u003chost\u003e\n```\n\nRun itamae for multiple hosts of a given role in parallel:\n\n```\n$ bundle exec kondate itamae-role \u003crole\u003e\n```\n\nRun serverspec for multiple hosts of a given role in parallel:\n\n```\n$ bundle exec kondate serverspec-role \u003crole\u003e\n```\n\n## Configuration\n\n`kondate init` provides a template directory tree such as:\n\n```\n.\n├── .kondate.conf     # kondate configuration\n├── bootstrap.rb      # itamae bootstrap\n├── hosts.yml         # manages hostnames and its roles\n├── properties        # manages run_lists and attributes\n│   ├── nodes         # host specific properties\n│   ├── roles         # role properties\n│   └── environments  # environment properties\n├── recipes           # itamae recipes\n│   ├── middleware    # middleware recipes\n│   │   └── base\n│   │       └── default.rb\n│   └── roles         # role recipes\n└── spec              # serverspec specs\n    ├── middleware    # middleware recipes specs\n    │   └── base_spec.rb\n    ├─  roles         # role recipes specs\n    └── spec_helper.rb\n├── secrets           # manages secrets attributes such as passwords\n│   ├── properties\n│   │   ├── environments\n│   │   ├── nodes\n│   │   └── roles\n│   ├── recipes\n│   │   ├── middleware\n│   │   └── roles\n│   └── spec\n│       ├── middleware\n│       └── roles\n```\n\n### .kondate.conf\n\nThe default .kondate.conf looks like below:\n\n```\nmiddlware_recipes_dir: recipes/middleware\nroles_recipes_dir: recipes/roles\nmiddleware_recipes_serverspec_dir: spec/middleware\nroles_recipes_serverspec_dir: spec/roles\nnodes_properties_dir: properties/nodes\nroles_properties_dir: properties/roles\nenvironments_properties_dir: properties/environments\nsecret_middlware_recipes_dir: secrets/recipes/middleware\nsecret_roles_recipes_dir: secrets/recipes/roles\nsecret_middleware_recipes_serverspec_dir: secrets/spec/middleware\nsecret_roles_recipes_serverspec_dir: secrets/spec/roles\nsecret_nodes_properties_dir: secrets/properties/nodes\nsecret_roles_properties_dir: secrets/properties/roles\nsecret_environments_properties_dir: secrets/properties/environments\nplugin_dir: lib\nhost_plugin:\n  type: file\n  path: hosts.yml\n```\n\nYou can customize the directory tree with this conf.\n\n#### Itamae options\n\nYou can configure itamae-kondate options on .kondate.conf, too as:\n\n```\nitamae_options:\n  shell: /bin/bash\n```\n\nSee `itamae-kondate --help` for option list.\n\n#### Serverspec options\n\nYou can configure serversepc-kondate options on .kondate.conf, too as:\n\n```\nserverspec_options:\n  vagrant: true\n```\n\nSee `serverspec-kondate --help` for option list.\n\n\n### hosts.yml\n\nThe default uses `file` host plugin, and `hosts.yml`. The contents of `hosts.yml` look like below:\n\n```\nlocalhost: [sample]\n```\n\nwhere keys are host names, and values are array of roles.\n\n```\n$ bundle exec kondate itamae \u003chost\u003e\n```\n\nworks as follows:\n\n1. obtains a role list from `hosts.yml`\n2. reads `properties/roles/#{role}.yml`, and find recipes and its attributes\n3. runs recipes\n\nYou can create your own host plugin. See `Host Plugin` section for more details.\n\n### properties\n\nProperty files are places to write recipes to run and attributes values.\n\n```\n├── properties        # manages run_lists and attributes\n│   ├── nodes         # host specific properties\n│   ├── roles         # role properties\n│   └── environments  # environment properties\n```\n\nAn example looks like below:\n\nproperties/roles/#{role}.yml\n\n```\nattributes:\n  ruby:\n    versions: [2.2.3]\n    gems:\n      2.2.3: [bundler]\n  node:\n    versions: [v0.12.2]\n    global: v0.12.2\n  nginx:\n```\n\nThe attributes variables are accessible like `attrs['ruby']['versions']`, which is equivalent and short version of `node['attributes']['ruby']['versions']` in recipes.\n\nYou can also prepare host-specific property files such as:\n\nproperties/nodes/#{host}.yml\n\n```\nattributes:\n  nginx:\n    worker_processes: 8\n```\n\nIn addition, you can also prepare environment property files such as:\n\nproperties/environments/`#{ENV['ENVIRONMENT'] || 'development'}`.yml\n\n```\nglobal_attributes:\n  aws_region: ap-northeast-1\n```\n\nwhere `global_attributes` is accessible like `global_attrs['aws_region']`, which is equivalent and short version of `node['global_attributes']['aws_region']` in recipes.\n\nThese files are merged on kondate execution in order of `environment` + `role` + `node` (`node` \u003e `role` \u003e `environment` in the strong order).\n\n### secret properties\n\nSecret properties are places to write confidential attributes.\n\n```\n├── secrets         # manages secrets attributes such as passwords\n│   └── properties\n│       ├── nodes\n│       ├── roles\n│       └── environments\n```\n\nAn example looks like below:\n\nsecrets/properties/roles/sample.yml\n\n```\nattributes:\n  base:\n    password: xxxxxxxx\n```\n\nThese files are merged with property files on kondate execution.\n\nHint: I manage secret property files on github private repository. ToDo: support encryption.\n\n### recipes\n\nPut you itamae recipes:\n\n```\n├── recipes         # itamae recipes\n│   ├── middleware  # middleware recipes\n│   │   └── base\n│   │       └── default.rb\n│   └── roles       # role recipes\n```\n\n`middleware recipes` are usual recipes to write how to install middleware such as `nginx`, `mysql`.\n\n`role recipes` are places to write role-specific provisioning. I often write recipes to create log directories for my app (role), for example.\n\nrecipes/roles/myapp/default.rb\n\n```ruby\ndirectory \"/var/log/myapp\" do\n  owner myapp\n  group myapp\n  mode 0755\nend\n```\n\n#### spec\n\nPut your serverspec specs.\n\n```\n└── spec            # serverspec specs\n    ├── middleware  # middleware recipes specs\n    └── roles       # role recipes specs\n```\n\nIt is required that `spec/spec_helper` has lines:\n\n```ruby\nset :host, ENV['TARGET_HOST']\nset :set_property, YAML.load_file(ENV['TARGET_NODE_FILE'])\n```\n\nbecause these ENVs are passed by `kondate serverspec`.\n\nConfiguring following lines for vagrant is also recommended:\n\n```\n  if ENV['TARGET_VAGRANT']\n    `vagrant up #{host}`\n\n    config = Tempfile.new('', Dir.tmpdir)\n    config.write(`vagrant ssh-config #{host}`)\n    config.close\n\n    Net::SSH::Config.for(host, [config.path])\n  else\n```\n\n`ENV['TARGET_VAGRANT']` is turned on if `kondate serverspec` is executed with `--vagrant` option.\n\nSee [templates/spec/spec_helper.rb](./lib/kondate/templates/spec/spec_helper.rb) for an example.\n\n### Exploring role files\n\nAvailable version: \u003e= v0.4.0\n\nAssume `role` is delimited with `-` (you can configure the delimiter) such as `myapp-web-staging`, this feature explores role files in order of:\n\n1. myapp-web-staging.yml\n1. myapp-web-base.yml\n1. myapp-web.yml\n1. myapp-base.yml\n1. myapp.yml\n1. base.yml\n\nThis makes it possible to share a property file, for example, `myapp-web.yml` among `myapp-web-staging` and `myapp-web-production` roles.\n\nTo enable this feature, you need to configure .kondate.conf as:\n\n```\nexplore_role_files: true # default is false\nrole_delimiter: \"-\" # default is -\n```\n\n## Host Plugin\n\nThe default reads `hosts.yml` to resolve roles of a host, but\nyou may want to resolve roles from AWS EC2 `roles` tag, or\nyou may want to resolve roles from your own host resolver API application.\n\nThus, `kondate` provides a plugin system to resolve hosts' roles.\n\n### Naming Convention\n\nYou must follow the below naming conventions:\n\n* gem name: kondate-host_plugin-xxx (xxx_yyy) (if you want to make a gem)\n* file name: lib/kondate/host_plugin/xxx.rb (xxx_yyy.rb)\n* class name: Kondate::HostPlugin::Xxx (XxxYyy)\n\nIf you want to put your own host plugin locally without publishing a gem, you can configure the location with .kondate.conf as:\n\n```\nplugin_dir: lib\n```\n\n### Interface\n\nWhat you have to implement are `#initialize`, `#get_environment`, and `#get_roles` methods.\n`get_hostinfo` method is an optional method to return arbitrary hostinfo of the host (available from kondate 0.2.0).\nHere is an example of file plugin:\n\n```ruby\nrequire 'yaml'\n\nmodule Kondate\n  module HostPlugin\n    # YAML format\n    #\n    # host1: [role1, role2]\n    # host2: [role1, role2]\n    class File \u003c Base\n      # @param [HashWithIndifferentAccess] config\n      def initialize(config)\n        super\n        raise ConfigError.new('file: path is not configured') unless config.path\n        @path = config.path\n\n        @roles_of_host = YAML.load_file(@path)\n        @hosts_of_role = {}\n        @roles_of_host.each do |host, roles|\n          roles.each do |role|\n            @hosts_of_role[role] ||= []\n            @hosts_of_role[role] \u003c\u003c host\n          end\n        end\n      end\n\n      # @param [String] host hostname\n      # @return [String] environment name\n      def get_environment(host)\n        ENV['ENVIRONMENT'] || 'development'\n      end\n\n      # @param [String] host hostname\n      # @return [Array] array of roles\n      def get_roles(host)\n        @roles_of_host[host]\n      end\n\n      # @param [String] role role\n      # @return [Array] array of hosts\n      #\n      # Available from kondate \u003e= 0.3.0\n      def get_hosts(role)\n        @hosts_of_role[role]\n      end\n\n      # Optional\n      #\n      # @param [String] host hostname\n      # @return [Hash] arbitrary hostinfo\n      def get_hostinfo(host)\n        {}\n      end\n    end\n  end\nend\n```\n\n### Config\n\n`config` parameter of `#initialize` is created from the configuration file (.kondate.conf):\n\n```\nhost_plugin:\n  type: file\n  path: hosts.yml\n```\n\n`config.type` and `config.path` is available in the above config.\n\n## See Also\n\n* [Itamae meetup #1 で「ぼくのかんがえた Itamae/Serverspec 構成フレームワーク 〜 板前の献立 〜」というトークをしてきた](http://blog.livedoor.jp/sonots/archives/46245484.html) (Japanese)\n\n## Development\n\n```\nbundle exec exe/kondate init .\nvagrant up\n```\n\n```\nbundle exec exe/kondate itamae vagrant-centos --vagrant --role sample\nbundle exec exe/kondate serverspec vagrant-centos --vagrant --role sample\n```\n\n## ToDo\n\nwrite tests\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsonots%2Fkondate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsonots%2Fkondate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsonots%2Fkondate/lists"}