@@ -1563,9 +1563,48 @@ static FnCallResult FnCallVariablesMatching(EvalContext *ctx, ARG_UNUSED const P
1563
1563
}
1564
1564
1565
1565
/*********************************************************************/
1566
+ static Bundle * GetBundleFromPolicy (const Policy * policy , const char * namespace , const char * bundlename )
1567
+ {
1568
+ assert (policy != NULL );
1569
+ const size_t bundles_length = SeqLength (policy -> bundles );
1566
1570
1567
- static FnCallResult FnCallGetMetaTags (EvalContext * ctx , ARG_UNUSED const Policy * policy , const FnCall * fp , const Rlist * finalargs )
1571
+ for (size_t i = 0 ; i < bundles_length ; i ++ )
1572
+ {
1573
+ Bundle * bp = SeqAt (policy -> bundles , i );
1574
+ if (StringEqual (bp -> name , bundlename ) && StringEqual (bp -> ns , namespace ))
1575
+ {
1576
+ return bp ;
1577
+ }
1578
+ }
1579
+ return NULL ;
1580
+ }
1581
+
1582
+ static Promise * GetPromiseFromBundle (const Bundle * bundle , const char * promise_type , const char * promiser )
1568
1583
{
1584
+ assert (bundle != NULL );
1585
+ const size_t sections_length = SeqLength (bundle -> sections );
1586
+ for (size_t i = 0 ; i < sections_length ; i ++ )
1587
+ {
1588
+ BundleSection * bsection = SeqAt (bundle -> sections , i );
1589
+ if (StringEqual (bsection -> promise_type , promise_type ))
1590
+ {
1591
+ const size_t promises_length = SeqLength (bsection -> promises );
1592
+ for (size_t i = 0 ; i < promises_length ; i ++ )
1593
+ {
1594
+ Promise * promise = SeqAt (bsection -> promises , i );
1595
+ if (StringEqual (promise -> promiser , promiser ))
1596
+ {
1597
+ return promise ;
1598
+ }
1599
+ }
1600
+ }
1601
+ }
1602
+ return NULL ;
1603
+ }
1604
+
1605
+ static FnCallResult FnCallGetMetaTags (EvalContext * ctx , const Policy * policy , const FnCall * fp , const Rlist * finalargs )
1606
+ {
1607
+ assert (fp != NULL );
1569
1608
if (!finalargs )
1570
1609
{
1571
1610
FatalError (ctx , "Function '%s' requires at least one argument" , fp -> name );
@@ -1574,18 +1613,63 @@ static FnCallResult FnCallGetMetaTags(EvalContext *ctx, ARG_UNUSED const Policy
1574
1613
Rlist * tags = NULL ;
1575
1614
StringSet * tagset = NULL ;
1576
1615
1577
- if (strcmp (fp -> name , "getvariablemetatags" ) == 0 )
1616
+ if (StringEqual (fp -> name , "getvariablemetatags" ))
1578
1617
{
1579
1618
VarRef * ref = VarRefParse (RlistScalarValue (finalargs ));
1580
1619
tagset = EvalContextVariableTags (ctx , ref );
1581
1620
VarRefDestroy (ref );
1582
1621
}
1583
- else if (strcmp (fp -> name , "getclassmetatags" ) == 0 )
1622
+ else if (StringEqual (fp -> name , "getclassmetatags" ))
1584
1623
{
1585
1624
ClassRef ref = ClassRefParse (RlistScalarValue (finalargs ));
1586
1625
tagset = EvalContextClassTags (ctx , ref .ns , ref .name );
1587
1626
ClassRefDestroy (ref );
1588
1627
}
1628
+ else if (StringEqual (fp -> name , "getbundlemetatags" ))
1629
+ {
1630
+ const char * bundleref = RlistScalarValue (finalargs );
1631
+ assert (bundleref != NULL );
1632
+ const Rlist * args = RlistFromSplitString (bundleref , ':' );
1633
+ const char * namespace = (args -> next == NULL ) ? "default" : RlistScalarValue (args );
1634
+ const char * name = RlistScalarValue ((args -> next == NULL ) ? args : args -> next );
1635
+
1636
+ const Bundle * bundle = GetBundleFromPolicy (policy , namespace , name );
1637
+ if (bundle == NULL )
1638
+ {
1639
+ Log (LOG_LEVEL_ERR ,
1640
+ "Function %s couldn't find bundle '%s' with namespace '%s'" ,
1641
+ fp -> name ,
1642
+ name ,
1643
+ namespace );
1644
+ return FnFailure ();
1645
+ }
1646
+ const Promise * promise = GetPromiseFromBundle (bundle , "meta" , "tags" );
1647
+ if (bundle == NULL )
1648
+ {
1649
+ Log (LOG_LEVEL_ERR ,
1650
+ "Function %s couldn't find meta tags in '%s:%s'" ,
1651
+ fp -> name ,
1652
+ namespace ,
1653
+ name );
1654
+ return FnFailure ();
1655
+ }
1656
+ Rlist * start = PromiseGetConstraintAsList (ctx , "slist" , promise );
1657
+ if (start == NULL )
1658
+ {
1659
+ Log (LOG_LEVEL_ERR ,
1660
+ "Function %s couldn't find meta tags constraint string list" ,
1661
+ fp -> name );
1662
+ return FnFailure ();
1663
+ }
1664
+
1665
+ tagset = StringSetNew ();
1666
+ Rlist * temp = start ;
1667
+ while (temp != NULL )
1668
+ {
1669
+ StringSetAdd (tagset , temp -> val .item );
1670
+ temp = temp -> next ;
1671
+ }
1672
+ }
1589
1673
else
1590
1674
{
1591
1675
FatalError (ctx , "FnCallGetMetaTags: got unknown function name '%s', aborting" , fp -> name );
@@ -10483,6 +10567,8 @@ const FnCallType CF_FNCALL_TYPES[] =
10483
10567
FNCALL_OPTION_COLLECTING , FNCALL_CATEGORY_DATA , SYNTAX_STATUS_NORMAL ),
10484
10568
FnCallTypeNew ("getvariablemetatags" , CF_DATA_TYPE_STRING_LIST , GETVARIABLEMETATAGS_ARGS , & FnCallGetMetaTags , "Collect the variable arg1's meta tags into an slist, optionally collecting only tag key arg2" ,
10485
10569
FNCALL_OPTION_VARARG , FNCALL_CATEGORY_UTILS , SYNTAX_STATUS_NORMAL ),
10570
+ FnCallTypeNew ("getbundlemetatags" , CF_DATA_TYPE_STRING_LIST , GETVARIABLEMETATAGS_ARGS , & FnCallGetMetaTags , "Collect the bundle arg1's meta tags into an slist, optionally collecting only tag key arg2" ,
10571
+ FNCALL_OPTION_VARARG , FNCALL_CATEGORY_UTILS , SYNTAX_STATUS_NORMAL ),
10486
10572
FnCallTypeNew ("grep" , CF_DATA_TYPE_STRING_LIST , GREP_ARGS , & FnCallGrep , "Extract the sub-list if items matching the regular expression in arg1 of the list or array or data container arg2" ,
10487
10573
FNCALL_OPTION_COLLECTING , FNCALL_CATEGORY_DATA , SYNTAX_STATUS_NORMAL ),
10488
10574
FnCallTypeNew ("groupexists" , CF_DATA_TYPE_CONTEXT , GROUPEXISTS_ARGS , & FnCallGroupExists , "True if group or numerical id exists on this host" ,
0 commit comments