inmanta-module-std 5.2.8__tar.gz → 8.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/PKG-INFO +2 -2
  2. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/README.md +2 -2
  3. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/inmanta_module_std.egg-info/PKG-INFO +2 -2
  4. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/inmanta_module_std.egg-info/SOURCES.txt +2 -5
  5. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/inmanta_module_std.egg-info/requires.txt +1 -1
  6. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/inmanta_plugins/std/__init__.py +117 -43
  7. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/inmanta_plugins/std/model/_init.cf +64 -210
  8. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/inmanta_plugins/std/model/testing.cf +3 -1
  9. inmanta_module_std-8.3.0/inmanta_plugins/std/resources.py +143 -0
  10. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/inmanta_plugins/std/setup.cfg +2 -2
  11. inmanta_module_std-8.3.0/inmanta_plugins/std/types.py +36 -0
  12. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/setup.cfg +2 -2
  13. inmanta_module_std-8.3.0/tests/test_agent.py +41 -0
  14. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/tests/test_agentconfig.py +11 -11
  15. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/tests/test_get_attribute.py +11 -11
  16. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/tests/test_mutables.py +31 -13
  17. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/tests/test_plugins.py +68 -13
  18. inmanta_module_std-8.3.0/tests/test_reference.py +54 -0
  19. inmanta_module_std-8.3.0/tests/test_resource.py +39 -0
  20. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/tests/test_template.py +11 -11
  21. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/tests/test_types.py +11 -11
  22. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/tests/test_unknown.py +11 -11
  23. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/tests/test_warnings.py +11 -11
  24. inmanta_module_std-5.2.8/inmanta_plugins/std/resources.py +0 -696
  25. inmanta_module_std-5.2.8/inmanta_plugins/std/types.py +0 -36
  26. inmanta_module_std-5.2.8/tests/test_agent.py +0 -41
  27. inmanta_module_std-5.2.8/tests/test_facts.py +0 -35
  28. inmanta_module_std-5.2.8/tests/test_file.py +0 -132
  29. inmanta_module_std-5.2.8/tests/test_in_docker.py +0 -43
  30. inmanta_module_std-5.2.8/tests/test_model.py +0 -73
  31. inmanta_module_std-5.2.8/tests/test_resources.py +0 -494
  32. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/MANIFEST.in +0 -0
  33. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/inmanta_module_std.egg-info/dependency_links.txt +0 -0
  34. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/inmanta_module_std.egg-info/not-zip-safe +0 -0
  35. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/inmanta_module_std.egg-info/top_level.txt +0 -0
  36. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/inmanta_plugins/std/templates/host_uri.j2 +0 -0
  37. {inmanta_module_std-5.2.8 → inmanta_module_std-8.3.0}/pyproject.toml +0 -0
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: inmanta-module-std
3
- Version: 5.2.8
3
+ Version: 8.3.0
4
4
  License: Apache 2.0
5
5
  Requires-Dist: Jinja2<4,>=3.1
6
6
  Requires-Dist: email_validator<3,>=1.3
7
7
  Requires-Dist: pydantic<3,>=1.10
8
- Requires-Dist: inmanta-core<14,>=8.7.0.dev
8
+ Requires-Dist: inmanta-core>=8.7.0.dev
@@ -1,4 +1,4 @@
1
- # std Module
1
+ # std module
2
2
 
3
3
  Inmanta base module that defines primitive types, entities and plugins regularly used when developing models.
4
4
 
@@ -42,7 +42,7 @@ class EntitlementResource(inmanta.resources.PurgeableResource):
42
42
  pass
43
43
  ```
44
44
 
45
- More information about developing Python Resources and Handlers can be found [here](https://docs.inmanta.com/inmanta-service-orchestrator/7/model_developers/handlers.html#handler).
45
+ More information about developing Python Resources and Handlers can be found [here](https://docs.inmanta.com/inmanta-service-orchestrator/latest/model_developers/handlers.html#handler).
46
46
 
47
47
  Another example would be to define a new resource that can be created / updated / removed. The following example is really basic
48
48
  and should probably not be implemented, an inventory would be better for that. But for the sake of a basic example, let's suppose that
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: inmanta-module-std
3
- Version: 5.2.8
3
+ Version: 8.3.0
4
4
  License: Apache 2.0
5
5
  Requires-Dist: Jinja2<4,>=3.1
6
6
  Requires-Dist: email_validator<3,>=1.3
7
7
  Requires-Dist: pydantic<3,>=1.10
8
- Requires-Dist: inmanta-core<14,>=8.7.0.dev
8
+ Requires-Dist: inmanta-core>=8.7.0.dev
@@ -17,14 +17,11 @@ inmanta_plugins/std/model/testing.cf
17
17
  inmanta_plugins/std/templates/host_uri.j2
18
18
  tests/test_agent.py
19
19
  tests/test_agentconfig.py
20
- tests/test_facts.py
21
- tests/test_file.py
22
20
  tests/test_get_attribute.py
23
- tests/test_in_docker.py
24
- tests/test_model.py
25
21
  tests/test_mutables.py
26
22
  tests/test_plugins.py
27
- tests/test_resources.py
23
+ tests/test_reference.py
24
+ tests/test_resource.py
28
25
  tests/test_template.py
29
26
  tests/test_types.py
30
27
  tests/test_unknown.py
@@ -1,4 +1,4 @@
1
1
  Jinja2<4,>=3.1
2
2
  email_validator<3,>=1.3
3
3
  pydantic<3,>=1.10
4
- inmanta-core<14,>=8.7.0.dev
4
+ inmanta-core>=8.7.0.dev
@@ -1,25 +1,26 @@
1
1
  """
2
- Copyright 2016 Inmanta
2
+ Copyright 2016 Inmanta
3
3
 
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
7
 
8
- http://www.apache.org/licenses/LICENSE-2.0
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
9
 
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
15
 
16
- Contact: code@inmanta.com
16
+ Contact: code@inmanta.com
17
17
  """
18
18
 
19
19
  import base64
20
20
  import hashlib
21
21
  import importlib
22
22
  import ipaddress
23
+ import json
23
24
  import logging
24
25
  import os
25
26
  import random
@@ -39,6 +40,8 @@ from jinja2.runtime import Undefined, missing
39
40
 
40
41
  # don't bind to `resources` because this package has a submodule named resources that will bind to `resources` when imported
41
42
  import inmanta.resources
43
+ from inmanta import util
44
+ from inmanta.agent.handler import LoggerABC
42
45
  from inmanta.ast import NotFoundException, OptionalValueException, RuntimeException
43
46
  from inmanta.config import Config
44
47
  from inmanta.execute.proxy import DynamicProxy, UnknownException
@@ -549,21 +552,16 @@ def type(obj: "any") -> "any":
549
552
 
550
553
 
551
554
  @plugin
552
- def sequence(i: "int", start: "int" = 0, offset: "int" = 0) -> "list":
555
+ def sequence(i: "int", start: "int" = 0) -> "list":
553
556
  """
554
557
  Return a sequence of i numbers, starting from zero or start if supplied.
555
558
 
556
559
  :param i: The number of elements in the sequence.
557
560
  :param start: The starting value for the sequence.
558
- :param offset: [Deprecated] An offset value (this parameter will be removed in the future).
559
561
 
560
562
  :return: A list containing the sequence of ints.
561
563
  """
562
- if offset != 0:
563
- logging.getLogger(__name__).warning(
564
- "The 'offset' parameter in the 'sequence' plugin is deprecated and will be removed in a future version."
565
- )
566
- return list(range(start, int(i) + start - offset))
564
+ return list(range(start, int(i) + start))
567
565
 
568
566
 
569
567
  @plugin
@@ -976,25 +974,40 @@ def server_port() -> "int":
976
974
 
977
975
 
978
976
  @plugin
979
- def get_env(name: "string", default_value: "string" = None) -> "string":
980
- env = os.environ
981
- if name in env:
982
- return env[name]
983
- elif default_value is not None:
984
- return default_value
985
- else:
986
- return Unknown(source=name)
977
+ def get_env(name: "string", default_value: "string?" = None) -> "string":
978
+ """
979
+ Get an environment variable, return Unknown if it doesn't exist.
980
+ Also log a warning to show the missing environment variable.
987
981
 
982
+ :param key: The name of the environment variable to get
983
+ """
984
+ val = os.getenv(name, default_value)
985
+ if val is not None:
986
+ return val
988
987
 
988
+ logging.getLogger(__name__).warning(
989
+ "Environment variable %s doesn't exist, returning Unknown(source=%s) instead",
990
+ name,
991
+ repr(name),
992
+ )
993
+ return Unknown(source=name)
994
+
995
+
996
+ @deprecated(replaced_by="int(std::get_env(...))")
989
997
  @plugin
990
- def get_env_int(name: "string", default_value: "int" = None) -> "int":
991
- env = os.environ
992
- if name in env:
993
- return int(env[name])
994
- elif default_value is not None:
995
- return default_value
996
- else:
997
- return Unknown(source=name)
998
+ def get_env_int(name: "string", default_value: "int?" = None) -> "int":
999
+ # This plugin will remain, but it is recommended to use getenv
1000
+ # instead
1001
+ val: str | int | None = os.getenv(name, default_value)
1002
+ if val is not None:
1003
+ return int(val)
1004
+
1005
+ logging.getLogger(__name__).warning(
1006
+ "Environment variable %s doesn't exist, returning Unknown(source=%s) instead",
1007
+ name,
1008
+ repr(name),
1009
+ )
1010
+ return Unknown(source=name)
998
1011
 
999
1012
 
1000
1013
  @plugin
@@ -1073,15 +1086,6 @@ def invert(value: "bool") -> "bool":
1073
1086
  return not value
1074
1087
 
1075
1088
 
1076
- @deprecated
1077
- @plugin
1078
- def to_number(value: "any") -> "number":
1079
- """
1080
- Convert a value to a number
1081
- """
1082
- return int(value)
1083
-
1084
-
1085
1089
  @plugin
1086
1090
  def list_files(ctx: Context, path: "string") -> "list":
1087
1091
  """
@@ -1290,3 +1294,73 @@ def ip_address_from_interface(
1290
1294
  :param ip_interface: The interface from where we will extract the ip address
1291
1295
  """
1292
1296
  return str(ipaddress.ip_interface(ip_interface).ip)
1297
+
1298
+
1299
+ @plugin
1300
+ def json_loads(s: "string") -> "any":
1301
+ """
1302
+ Deserialize s (a string instance containing a JSON document) to an inmanta dsl object.
1303
+
1304
+ :param s: The serialized json string to parse.
1305
+ """
1306
+ return json.loads(s)
1307
+
1308
+
1309
+ @plugin
1310
+ def json_dumps(obj: "any") -> "string":
1311
+ """
1312
+ Serialize obj to a JSON formatted string.
1313
+
1314
+ :param obj: The inmanta object that should be serialized as json.
1315
+ """
1316
+ return json.dumps(obj, default=util.internal_json_encoder)
1317
+
1318
+
1319
+ @plugin
1320
+ def format(__string: "string", *args: "any", **kwargs: "any") -> "string":
1321
+ """
1322
+ Format a string using python string formatter, and accepting statements which
1323
+ native inmanta f-string doesn't support (such as accessing dict values)
1324
+
1325
+ :param __string: The string to apply formatting to
1326
+ :param args: The positional arguments to feed into the `str.format` method
1327
+ :param kwargs: The keyword arguments to feed into the `str.format` method
1328
+ """
1329
+ return __string.format(*args, **kwargs)
1330
+
1331
+
1332
+ try:
1333
+ from inmanta.references import Reference, reference
1334
+
1335
+ @reference("std::Environment")
1336
+ class EnvironmentReference(Reference[str]):
1337
+ """A reference to fetch environment variables"""
1338
+
1339
+ def __init__(self, name: str | Reference[str]) -> None:
1340
+ """
1341
+ :param name: The name of the environment variable.
1342
+ """
1343
+ super().__init__()
1344
+ self.name = name
1345
+
1346
+ def resolve(self, logger: LoggerABC) -> str:
1347
+ """Resolve the reference"""
1348
+ env_var_name = self.resolve_other(self.name, logger)
1349
+ logger.debug("Resolving environment variable %(name)s", name=self.name)
1350
+ value = os.getenv(env_var_name)
1351
+ if value is None:
1352
+ raise LookupError(f"Environment variable {env_var_name} is not set")
1353
+ return value
1354
+
1355
+ @plugin
1356
+ def create_environment_reference(name: str | Reference[str]) -> Reference[str]:
1357
+ """Create an environment reference
1358
+
1359
+ :param name: The name of the variable to fetch from the environment
1360
+ :return: A reference to what can be resolved to a string
1361
+ """
1362
+ return EnvironmentReference(name=name)
1363
+
1364
+ except ImportError:
1365
+ # Reference are not yet supported by this core version
1366
+ pass
@@ -103,7 +103,7 @@ typedef ipv_any_network as string matching std::validate_type("pydantic.IPvAnyNe
103
103
  """
104
104
  A string matching the requiremenst of ipv4_network or ipv6_network.
105
105
  """
106
- typedef negative_float as number matching std::validate_type("pydantic.NegativeFloat", self)
106
+ typedef negative_float as float matching std::validate_type("pydantic.NegativeFloat", self)
107
107
  """
108
108
  A floating point number less than zero.
109
109
  """
@@ -111,7 +111,7 @@ typedef negative_int as int matching std::validate_type("pydantic.NegativeInt",
111
111
  """
112
112
  A integer number less than zero.
113
113
  """
114
- typedef positive_float as number matching std::validate_type("pydantic.PositiveFloat", self)
114
+ typedef positive_float as float matching std::validate_type("pydantic.PositiveFloat", self)
115
115
  """
116
116
  A floating point number greater than zero.
117
117
  """
@@ -212,6 +212,25 @@ entity ManagedDevice:
212
212
  hoststring name
213
213
  end
214
214
 
215
+ entity Dataclass:
216
+ """
217
+ Super class for inmanta entities that have a python counterpart.
218
+
219
+ The python counterpart is expect to be
220
+ - a frozen dataclass,
221
+ - with the same name
222
+ - in the plugins package of this module
223
+ - in the corresponding submodule
224
+ - with the exact same fields
225
+
226
+ The Inmanta entity is expect to
227
+ - have no relations
228
+ - have no indexes
229
+ - have only std::none as implementation
230
+
231
+ """
232
+ end
233
+
215
234
  entity Host extends ManagedDevice:
216
235
  """
217
236
  A host models a server or computer in the managed infrastructure that
@@ -234,183 +253,6 @@ index Host(name)
234
253
 
235
254
  typedef hoststring as string matching /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*$/
236
255
 
237
- entity Reload extends Resource:
238
- """
239
- An entity to make the (old) reload mechanism compatible with the event mechanism
240
-
241
- :attr reload: If a service requires this file, reload or restart the service when this file
242
- changes.
243
- """
244
- bool reload=false
245
- bool send_event=undef
246
- end
247
-
248
- implementation reload for Reload:
249
- self.send_event=self.reload
250
- end
251
-
252
- entity File extends Reload, PurgeableResource:
253
- """
254
- This represents a file on the filesystem
255
-
256
- :attr path: The path of the file
257
- :attr mode: The permissions of the file
258
- :attr owner: The owner of the file
259
- :attr group: The group of the file
260
- :attr content: The file contents
261
- """
262
- string path
263
- int mode
264
- string owner
265
- string group
266
- string content
267
- bool purge_on_delete=false
268
- bool send_event=undef
269
- string content_seperator="\n"
270
- end
271
-
272
- implement File using reload, fileHost
273
-
274
- entity Content:
275
- """
276
- A content block as a prefix or suffix to a file. This blocks are only merged with the content at export time. This
277
- is an advanced pattern that can be used to speed up the compilation in very specific use cases.
278
-
279
- :attr sorting_key: The key to use to sort the content blocks in the same list. When this attribute is not set
280
- value is used as sorting key.
281
- :attr value: The value to prepend or append
282
- """
283
- string? sorting_key=null
284
- string value
285
- end
286
-
287
- implement Content using std::none
288
-
289
- File.prefix_content [0:] -- Content
290
- File.suffix_content [0:] -- Content
291
-
292
- entity ConfigFile extends File:
293
- """
294
- A file with often used defaults for configuration files.
295
- """
296
- int mode=644
297
- string owner="root"
298
- string group="root"
299
- end
300
-
301
- implement ConfigFile using reload, fileHost
302
-
303
- File.host [1] -- Host.files [0:]
304
-
305
- index File(host, path)
306
-
307
- implementation fileHost for File:
308
- self.requires = self.host.requires
309
- end
310
-
311
- # the state of a service
312
- typedef service_state as string matching self == "running" or self == "stopped"
313
-
314
- # a service that is managed
315
- entity Service extends Reload:
316
- """
317
- Manage a service on a host.
318
-
319
- :attr name: The name of the service to manage
320
- :attr state: The desired state of the service. Valid values are 'running' or 'stopped'
321
- :attr onboot: Should the service start on boot.
322
- """
323
- string name
324
- service_state state
325
- bool onboot
326
- end
327
-
328
- implement Service using reload, serviceHost
329
-
330
- Service.host [1] -- Host.services [0:]
331
-
332
- index Service(host, name)
333
-
334
- implementation serviceHost for Service:
335
- self.requires = self.host.requires
336
- end
337
-
338
- # the state of a package
339
- typedef package_state as string matching self == "installed" or self == "removed" or self == "latest"
340
-
341
- entity Package extends Reload:
342
- """
343
- A software package installed on a managed device.
344
-
345
- :attr name: The name of the package to manage
346
- :attr state: The state of the package. Valid values are 'installed', 'removed' or 'latest'.
347
- latest will upgrade the package when an update is available.
348
- """
349
- string name
350
- package_state state
351
- end
352
-
353
- implement Package using reload, pkgHost
354
-
355
- Host.packages [0:] -- Package.host [1]
356
-
357
- index Package(host, name)
358
-
359
- implementation pkgHost for Package:
360
- self.requires = self.host.requires
361
- end
362
-
363
- # a directory
364
- entity Directory extends Reload, PurgeableResource:
365
- """
366
- A directory on the filesystem
367
- """
368
- string path
369
- int mode
370
- string owner
371
- string group
372
- bool purge_on_delete=false
373
- end
374
-
375
- implement Directory using reload, dirHost
376
-
377
- entity DefaultDirectory extends Directory:
378
- """
379
- A directory that is world readable. It is also writable for its owner root.
380
- """
381
- int mode=755
382
- string owner="root"
383
- string group="root"
384
- end
385
-
386
- implement DefaultDirectory using reload, dirHost
387
-
388
- Host.directories [0:] -- Directory.host [1]
389
-
390
- index Directory(host, path)
391
-
392
- implementation dirHost for Directory:
393
- self.requires = self.host.requires
394
- end
395
-
396
- # symlink
397
- entity Symlink extends Reload, PurgeableResource:
398
- """
399
- A symbolic link on the filesystem
400
- """
401
- string source
402
- string target
403
- bool purge_on_delete=false
404
- bool send_event=undef
405
- end
406
-
407
- implement Symlink using std::reload, symHost
408
-
409
- Host.symlinks [0:] -- Symlink.host [1]
410
-
411
- implementation symHost for Symlink:
412
- self.requires = self.host.requires
413
- end
414
256
 
415
257
  # define operating systems
416
258
  unix = OS(name = "unix")
@@ -431,7 +273,7 @@ entity OS:
431
273
  :attr python_cmd: Specifies what command should be used to launch the python interpreter on the other end
432
274
  """
433
275
  string name
434
- number version = 0.0
276
+ float version = 0.0
435
277
  string? python_cmd = "python"
436
278
  end
437
279
 
@@ -558,15 +400,15 @@ end
558
400
  implement MutableString using std::none
559
401
 
560
402
 
561
- entity MutableNumber:
403
+ entity MutableInt:
562
404
  """
563
- Wrapper for number values, used to pass a number out of an if statement or to
564
- use relations to create a mutuable set of numbers.
405
+ Wrapper for int values, used to pass a int out of an if statement or to
406
+ use relations to create a mutuable set of int.
565
407
 
566
408
  :Example:
567
409
  .. code-block:: inmanta
568
410
 
569
- attr_a = std::MutableNumber()
411
+ attr_a = std::MutableInt()
570
412
  if some_condition:
571
413
  attr_a.value = 3
572
414
  else:
@@ -579,59 +421,71 @@ use relations to create a mutuable set of numbers.
579
421
  entity Test:
580
422
  end
581
423
 
582
- Test.string_list [0:] -- std::MutableNumber
424
+ Test.string_list [0:] -- std::MutableInt
583
425
 
584
426
  a = Test()
585
- a.string_list += std::MutableNumber(value=3)
586
- a.string_list += std::MutableNumber(value=7)
427
+ a.string_list += std::MutableInt(value=3)
428
+ a.string_list += std::MutableInt(value=7)
587
429
  """
588
- number? value
430
+ int? value
589
431
  end
590
432
 
591
- implement MutableNumber using std::none
433
+ implement MutableInt using std::none
592
434
 
593
435
 
594
- entity MutableBool:
436
+ entity MutableFloat:
595
437
  """
596
- Wrapper for boolean values, used to pass a boolean out of an if statement.
438
+ Wrapper for float values, used to pass a float out of an if statement or to
439
+ use relations to create a mutable set of float.
597
440
 
598
441
  :Example:
599
442
  .. code-block:: inmanta
600
443
 
601
- attr_a = std::MutableBool()
444
+ attr_a = std::MutableFloat()
602
445
  if some_condition:
603
- attr_a.value = True
446
+ attr_a.value = 3.0
604
447
  else:
605
- attr_a.value = Null
448
+ attr_a.value = 4.0
449
+ end
450
+
451
+ :Example:
452
+ .. code-block:: inmanta
453
+
454
+ entity Test:
606
455
  end
607
456
 
457
+ Test.string_list [0:] -- std::MutableFloat
458
+
459
+ a = Test()
460
+ a.string_list += std::MutableFloat(value=3.0)
461
+ a.string_list += std::MutableFloat(value=7.0)
608
462
  """
609
- bool? value
463
+ float? value
610
464
  end
611
465
 
612
- implement MutableBool using std::none
466
+ implement MutableFloat using std::none
613
467
 
614
468
 
615
- entity Packages:
616
- """ Defined the state for multiple packages at once
617
-
618
- :param name: A list of package names
619
- :param state: The state of the package
469
+ entity MutableBool:
620
470
  """
621
- string[] name
622
- std::package_state state="installed"
623
- end
624
-
625
- Packages.host [1] -- std::Host
471
+ Wrapper for boolean values, used to pass a boolean out of an if statement.
626
472
 
627
- implement Packages using pkgs
473
+ :Example:
474
+ .. code-block:: inmanta
628
475
 
629
- implementation pkgs for Packages:
630
- for pkg in name:
631
- std::Package(host=self.host, name=pkg, state=self.state, requires=self.requires, provides=self.provides)
476
+ attr_a = std::MutableBool()
477
+ if some_condition:
478
+ attr_a.value = True
479
+ else:
480
+ attr_a.value = Null
632
481
  end
482
+
483
+ """
484
+ bool? value
633
485
  end
634
486
 
487
+ implement MutableBool using std::none
488
+
635
489
  entity ResourceSet:
636
490
  """
637
491
  A ResourceSet describes resources that logically belong together,
@@ -21,15 +21,17 @@ entity NullResource extends ManagedResource, PurgeableResource:
21
21
  A resource that does nothing, for use in tests and examples
22
22
 
23
23
  :attr name: the name of this resource
24
+ :attr value: a value this resource can cary, has no purpose
24
25
  :attr agentname: the name of the agent to deploy this resource on
25
26
  :attr fail: when true, this resource will always fail on both dryrun and deploy
26
27
  """
27
28
  string name = "null"
28
29
  string agentname = "internal"
30
+ string value = ""
29
31
  bool send_event = true
30
32
  bool fail = false
31
33
  end
32
34
 
33
35
  index NullResource(agentname, name)
34
36
 
35
- implement NullResource using std::none
37
+ implement NullResource using std::none